Nitter/Nonitter Companion for Twitter to Nitter Redirector with Skip

Companion script for X.com/Twitter to Nitter Redirector, adds ?nonitter to Twitter icon links on nitter.net to prevent redirect back to Nitter

// ==UserScript==
// @name        Nitter/Nonitter Companion for Twitter to Nitter Redirector with Skip
// @namespace   https://greasyfork.org/nl/users/1197317-opus-x
// @version     1.01
// @description Companion script for X.com/Twitter to Nitter Redirector, adds ?nonitter to Twitter icon links on nitter.net to prevent redirect back to Nitter
// @author      Opus-X
// @license     MIT
// @match       https://nitter.net/*
// @match       https://xcancel.com/*
// @grant       none
// @run-at      document-idle
// ==/UserScript==

(function() {
    'use strict';

    function appendNonitter() {
        console.log('Running appendNonitter on nitter.net');
        const links = document.querySelectorAll('a.icon-bird[title="Open in Twitter"]');
        links.forEach(link => {
            let href = link.getAttribute('href');
            // Skip if already has nonitter
            if (!href.includes('?nonitter') && !href.includes('&nonitter')) {
                console.log('Modifying link: ' + href);
                if (href.includes('?')) {
                    link.href = href + '&nonitter';
                } else {
                    link.href = href + '?nonitter';
                }
                console.log('Modified to: ' + link.href);
            }
        });
    }

    // Run on initial load
    appendNonitter();

    // Observe for dynamic content
    const observer = new MutationObserver(() => {
        console.log('Mutation detected, running appendNonitter');
        appendNonitter();
    });
    observer.observe(document.body, { childList: true, subtree: true });

    // Additional run after 2 seconds for late-loaded content
    setTimeout(appendNonitter, 2000);
})();