ChatGPT UTM Remover

Removes utm_source=chatgpt.com from link URLs

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         ChatGPT UTM Remover
// @namespace    https://github.com/GooglyBlox
// @version      1.0
// @description  Removes utm_source=chatgpt.com from link URLs
// @author       GooglyBlox
// @match        https://chatgpt.com/c/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    function cleanUrl(url) {
        try {
            const urlObj = new URL(url);
            if (urlObj.searchParams.get('utm_source') === 'chatgpt.com') {
                urlObj.searchParams.delete('utm_source');
                return urlObj.toString();
            }
            return null;
        } catch {
            return null;
        }
    }

    function cleanLink(link) {
        const cleanedUrl = cleanUrl(link.href);
        if (cleanedUrl) {
            link.href = cleanedUrl;
            if (link.hasAttribute('alt')) {
                const cleanedAlt = cleanUrl(link.alt);
                if (cleanedAlt) {
                    link.alt = cleanedAlt;
                }
            }
        }
    }

    function cleanLinks(root = document) {
        const links = root.querySelectorAll('a[href]');
        links.forEach(cleanLink);
    }

    cleanLinks();

    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            if (mutation.type === 'attributes') {
                const target = mutation.target;
                if (target.tagName === 'A' && target.href) {
                    cleanLink(target);
                }
            } else if (mutation.type === 'childList') {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        if (node.tagName === 'A' && node.href) {
                            cleanLink(node);
                        }
                        cleanLinks(node);
                    }
                });
            }
        });
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['href', 'alt']
    });
})();