30
posted ago by magaphraust ago by magaphraust +30 / -0

Just thought I'd share a quick and dirty tampermonkey script I made the works on x.com it just adds a floating header at the top of the page, with a button to open nitter in a new tab, and another button to copy the nitter link to the clipboard. I use this all the time now, if I want to see twitter comments, or to post the link in threads for other people to use. (since I don't have an account)

You just need the TamperMonkey Plugin for whatever browser you use. Then add this as a new user script. (Don't think you can get this on mobile)

WARNING - It can be dangerous to just blindly copy user scripts. If you have basic knowledge you can clearly see this script only needs permissions to open in new tab, set clipboard, and uses font-awesome for icons. But bad actors can make scripts to harvest your data. The majority of this script is just styling (which I hard coded for dark mode). I have it set up to go to nitter.poast.org, there are a couple other alternatives out there, so you can easily change the url under "\\ Change url here if you want"

// ==UserScript==
// @name         X.com → Nitter dark‑mode shortcut
// @version      1.0
// @description  Adds Nitter links to X
// @match        https://x.com/*
// @grant        GM_openInTab
// @grant        GM_setClipboard
// @run-at       document-idle
// @require      https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/js/all.min.js
// ==/UserScript==

(function () {
    'use strict';

    /**
     * Build nitter link from current location path (ignore query string & hash)
     **/
    function getNitterUrl() {
        // Change url here if you want
        return `https://nitter.poast.org${location.pathname}`;
    }

    /* -------------------------------------------------
       Floating header bar
       ------------------------------------------------- */
    const barHeight = 36; // px

    const bar = document.createElement('div');
    bar.style.position = 'fixed';
    bar.style.top = '0';
    bar.style.left = '18%';
    bar.style.width = '60%';
    bar.style.margin = '0 auto';
    bar.style.height = `${barHeight}px`;
    bar.style.background = '#15202b';
    bar.style.borderBottom = '1px solid #38444d';
    bar.style.zIndex = '9999';
    bar.style.display = 'flex';
    bar.style.alignItems = 'center';
    bar.style.justifyContent = 'center';
    bar.style.fontFamily = 'Helvetica, Arial, sans-serif';
    bar.style.fontSize = '14px';
    bar.style.color = '#fff';

    // ---- "No X" label ----
    const nox = document.createElement('span');
    nox.style.marginRight = '1px';
    nox.innerHTML = '<span class="fa-stack fa-2x"><i class="fa-solid fa-brands fa-x-twitter fa-stack-1x"></i><i class="fa-solid fa-ban fa-stack-1x" style="color:#8b0000"></i></span>';
    bar.appendChild(nox);

    // ---- "Nitter" logo (close enough) ----
    const nlogo = document.createElement('span');
    nlogo.style.marginRight = '1px';
    nlogo.innerHTML = '<i class="fa-solid fa-n"></i>';
    bar.appendChild(nlogo);

    // ---- "Nitter" label ----
    const label = document.createElement('span');
    label.textContent = 'itter';
    label.style.marginRight = '12px';
    bar.appendChild(label);

    // ---- Open‑in‑new‑tab icon ----
    const openLink = document.createElement('a');
    openLink.href = getNitterUrl();
    openLink.title = 'Open Nitter page in new tab';
    openLink.style.marginRight = '12px';
    openLink.style.color = '#1da1f2';
    openLink.style.textDecoration = 'none';
    openLink.innerHTML = '<i class="fa-solid fa-right-from-bracket"></i>';
    openLink.addEventListener('click', function (e) {
        e.preventDefault();
        if (typeof GM_openInTab === 'function') {
            GM_openInTab(openLink.href, { active: true, insert: true });
        } else {
            window.open(openLink.href, '_blank');
        }
    });
    bar.appendChild(openLink);

    // ---- Copy‑to‑clipboard icon ----
    const copyBtn = document.createElement('button');
    copyBtn.title = 'Copy Nitter link';
    copyBtn.style.border = 'none';
    copyBtn.style.background = 'transparent';
    copyBtn.style.cursor = 'pointer';
    copyBtn.style.color = '#1da1f2';
    copyBtn.style.fontSize = '14px';
    copyBtn.innerHTML = '<i class="fa-regular fa-copy"></i>';
    copyBtn.addEventListener('click', function () {
        const url = getNitterUrl();
        if (typeof GM_setClipboard === 'function') {
            GM_setClipboard(url);
        } else if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(url);
        } else {
            const ta = document.createElement('textarea');
            ta.value = url;
            document.body.appendChild(ta);
            ta.select();
            document.execCommand('copy');
            document.body.removeChild(ta);
        }
        // brief visual feedback
        copyBtn.innerHTML = '✅';
        setTimeout(() => (copyBtn.innerHTML = '<i class="fa-regular fa-copy"></i>'), 1200);
    });
    bar.appendChild(copyBtn);

    document.body.prepend(bar);
    const root = document.documentElement;
    const currentPadding = parseInt(window.getComputedStyle(root).paddingTop, 10) || 0;
    root.style.paddingTop = `${currentPadding + barHeight}px`;

    const updateLinks = () => {
        const newUrl = getNitterUrl();
        openLink.href = newUrl;
    };

    // Observe title changes (Twitter updates title on navigation)
    const titleObserver = new MutationObserver(updateLinks);
    const titleEl = document.querySelector('title');
    if (titleEl) titleObserver.observe(titleEl, { childList: true });

    // Fallback: listen to popstate events
    window.addEventListener('popstate', updateLinks);
})();