Twitter (aka “X” aka “Xitter”) individual tweet (aka “xeet”) page re-title-er (userscript workaround for Twitter broken-ness)

Categories
Contrivances HerpDerp JavaScript

To those amongst you who are active on Twitter (now known as X and colloquially to some as Xitter), even if you’re simply browsing and not actively posting/tweeting/xeeting, and who use browser bookmarks: today’s post ought to be right up your alley!

First, some background. Note: I don’t use smartphone social media apps, so we’re talking exclusively about how Twitter works as a website in a desktop/laptop PC web browser. Tweets have permalinks. They’re the timestamps, with ever-changing anchor text that updates as time elapses from the moment it was posted, on the top line of each tweet, furthest to the right from the user’s little round-cropped avatar image, their user name, their blue check (if any), and their user @handle. For something posted between five and six minutes earlier, the permalink text would be, for example, 5m.

My modus operandi on Twitter is to skim a bit of the reverse-chronological stream of tweets of people whose accounts I follow (in the Following feed, never the For You feed) and Ctrl+ interesting tweets’ permalinks so that they open in new browser tabs, in the background. I rarely switch to the new tab. At some point, I bookmark all of the tabs in that browser window (the keyboard shortcut for this is Ctrl+Shift+D, at least in the browsers I use).

This is the default behavior with respect to page titles seen when one opens an individual tweet in a new browser tab in the background. Notice that the page titles of those background tabs are simply x.com URLs? Mousing-over a tab triggers the site to fully load the visible content and update the page title.
This is the default behavior with respect to page titles seen when one opens an individual tweet in a new browser tab in the background. Notice that the page titles of those background tabs are simply x.com URLs? And see how mousing-over a tab triggers the site to fully load the visible content and update the page title.

The problem is that, for some reason, Twitter doesn’t display the visual contents of a tweet or give the page a useful title until you view that page or at least hover over the browser tab in question with your mouse cursor. Until you do, the page is blank and the title is simply the URL of that page (i.e. that tweet’s permalink URL). I don’t know why the site works this way and knowing wouldn’t make any difference for my purposes. The result for me, however, is that bookmarking all the tabs in my current browser window after skimming Twitter yields a bookmarks folder full of inscrutable and fairly useless URLs to tweets, unless I cycle through all of the tabs and linger in each tab long enough to trigger the loading and page re-titling process. If my description of this issue is as clear as mud, check out the animated GIF screen recording embedded above.

Doing the same thing (opening tweets in background browser tabs) with my userscript installed. The page titles update to reflect the author and contents of the tweets.
Doing the same thing (opening tweets in background browser tabs) with my userscript installed. The page titles update to reflect the author and contents of the tweets.

As a fix, I’ve slapped together a userscript that checks the title on an individual tweet’s page and, if it’s still just a URL, re-writes it to something useful: ReTitle-er-for-Twitter.user.js.

If the soupy markup on the Twitter site changes and if I update the script to cope with the resulting breakage, the link in the preceding paragraph may take you to a working version. Currently, however, what follows is the userscript in its glorious entirety. Apologies for the broken syntax highlighting. The plugin I’m running seems to be choking on single-quotes (single quotation marks) used as punctuation inside multi-line comments.

X (Twitter/Xitter) Individual Xeet/Tweet in-new-tab re-title-er (full text)

// ==UserScript==
// @name         X (Twitter/Xitter) Individual Xeet/Tweet in-new-tab re-title-er
// @namespace    http://www.eatdirtshit.rocks/
// @version      2024-10-31
// @downloadURL  http://eatdirtshit.rocks/userscripts/ReTitle-er-for-Twitter.user.js
// @description  When you open a tweet (or xeet or whatever) in a new browser tab but don't switch to that tab, its page title is just the URL for the tweet. To get the page title to update to the user's name and the text of their tweet (and for the contents of that tab to fully, visibly load), you have to either hover your mouse cursor over the tab for a moment or switch to that tab at least briefly. If you've opened many tweets in separate tabs while browsing your Twitter feed and bookmark them all at once (e.g. via Ctrl-Shift-D) as a folder full of bookmarks, you have little chance of later being able to look at your bookmarks and find a particular tweet that interested you. This userscript is an attempt at addressing this issue, by digging up the user's name, their @handle, and the tweet's contents and setting the title of each tweet opened in the browser. It's re-run periodically because I have observed that, occasionally, the Twitter site re-loads or otherwise monkeys with a background-tab-loaded tweet's page in a way that causes the title to revert to the pernicious URL-title format.
// @author       Brian Donovan
// @match        https://x.com/*/status/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

 'use strict';

(function() {

    var reTitleThisTweetPage = function(){

        /*
         If the page title has already updated or been re-written and is not the URL, then skip the rest of
         this run.
         */
        if (document.title.startsWith('x.com/')) {
            return;
        }

        /* If the linked tweet is a reply to another tweet (possibly several levels down from an original
        tweet), then going after the details for the first tweet on that page won't yield the details for the
        tweet you've loaded. So we get the 'status' (tweet) ID from the URL, hunt for it in the page (in the
        href attribute value for that tweet's permalink), and then use  XPath to ascend back up to the
        container for the target tweet.
        */
        var arrUriPieces = document.documentURI.split('/');
        var strLinkedTweetId = arrUriPieces[arrUriPieces.length - 1];
        var strXPathToTweet = '//*[contains(@href,"'+strLinkedTweetId+'")]/../../../../../../..';
        var ndONS_XPathResultForTweet = document.evaluate(strXPathToTweet, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

        /*
         Get contents  of the target tweet and the user's name and @ handle through a combined XPath evaluation.
         */
        var ndONS_XPathResultForTweetText = document.evaluate('div[last()]//div[@data-testid="tweetText"] | div[last() -1]//div[@data-testid="User-Name"]', ndONS_XPathResultForTweet.snapshotItem(0), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

        /*
         The tweet may be comprised solely of images or a video and not contain any text.
         */
        var strTweetText = '  <IMG or VIDEO only>  ';
        if (ndONS_XPathResultForTweetText.snapshotItem(1)) {
            strTweetText = ': '+ ndONS_XPathResultForTweetText.snapshotItem(1).textContent;
        }

        /*
        Get the user's name and their @handle and compose and set the page title.
        */
        if (ndONS_XPathResultForTweetText.snapshotItem(0)) {
            document.title = ndONS_XPathResultForTweetText.snapshotItem(0).childNodes[0].textContent +
                ' ' +
                ndONS_XPathResultForTweetText.snapshotItem(0).childNodes[1].textContent +
                strTweetText;
        }

    }

    /*
     I've gone with a 10-sec interval between runs in hopes of preventing this userscript from being excessively resource-intensive. YMMV.
     */
    document.addEventListener('load', function(){setInterval(reTitleThisTweetPage, 10000)}, true);

    }
)();