In the last week, the website "Twitter" added a view counter to every single post on the site. For various reasons, various people dislike this change.
I have figured out you can undo the change in Web Twitter using the "uBlock Origin" extension for Chrome and Firefox. (This will also block all advertisements on Twitter; apologies if that was not something you wanted.) Install the plugin, then go to its settings (click the badge that appears in the browser toolbar after installation, or follow these instructions), then click on "My Filters" and paste in these two lines:
! Block Twitter views/analytics UI elements added in 2022
twitter.com##div:has(>a[href$="/analytics"]:not([role="menuitem"]))
After "Applying", this will remove all versions of "N views" from under posts, as well as the big analytics link under some posts (and the little analytics link that appears under posts predating the view counter). You will still be able to access a post's analytics by using the ⋯ menu next to it (see "Some interesting facts" below for more on that).
While creating this, I learned enough about uBlock I was able to generally improve my old Twitter uBlock filters. Here are some additional filters that remove what I would consider some of Twitter's more parasocial features, as well as the custom font. Feel free to copy and paste whichever lines you like.
! Block "Verified" tab in Twitter notifications
twitter.com##div:has(>a[href$="/notifications/verified"])
! Block Twitter "What's Happening" trending box
twitter.com##div[aria-label$="Trending now"]
! Block Twitter "Who to Follow" box
twitter.com##div:has(>aside[aria-label="Who to follow"])
! Block trending/news section on Twitter search page
twitter.com##div[aria-label="Timeline: Explore"]
! Block "Twitter Blue" link in sidebar/anywhere
twitter.com##a[aria-label$="Twitter Blue"]
! Disable Twitter's ugly font with the weird "g"
https://abs.twimg.com/fonts/chirp-bold-web.woff
https://abs.twimg.com/fonts/chirp-heavy-web.woff
https://abs.twimg.com/fonts/chirp-regular-web.woff
https://abs.twimg.com/fonts/chirp-medium-web.woff
This won't work if you use a phone app, or a browser (like Safari) that doesn't support uBlock Origin. However, the format used above is based on the standard CSS selectors, so it should be pretty easy to port any of these filters to other ad blockers or CSS-tweak plugins (they may even work without alterations). And phone apps are actually the easy case because simply using any third-party Twitter client will remove all the new Musk-related features, because they are not in the public API.
I do not hope that any of this will improve your Twitter experience, because I do not think you should use Twitter; I do not think anyone should use Twitter, at this point. However, some people may still need to look at Twitter for work or other reasons, so I would be glad if this can reduce the amount of unhappiness in your life.
Expand below to see how this works ⬇️
How this works
As mentioned, the uBlock Origin filter syntax is based on CSS selectors, which are well-documented and bizarrely powerful. Creating selector-based rules is usually pretty difficult for Twitter because it uses obfuscation for its CSS classes and ids; attempting to use uBlock Origin's "eyedropper" tool to create such a rule on Twitter usually results in either a rule based on a very specific obfuscated class name (and these rules break when the obfuscated names change, which is not infrequent), or a positional rule using "nth-of-type", which is bad because it can wind up blocking entirely unrelated elements that just happen to appear at the same place in the page under other circumstances. Twitter is probably not obfuscating these things specifically to frustrate user-css; probably it's just a byproduct of some React-like library. But boy howdy does it frustrate these things.
Regardless of why Twitter obfuscates their HTML, there are two things they cannot obfuscate. One is accessibility attributes such as Aria, which obviously must remain clearly human-intelligible or the site will not be accessible. The other is links. The "N views" and "Verified"-tab rules above work by detecting divs containing links on twitter.com to URLs ending in "/analytics" or "/notifications/verified". (You'd think this would have collateral damage in the form of blocking links to external sites that just happen to end in "/analytics", but amusingly, Twitter does obfuscate links to external sites using their link shortener, so you're safe! It's only links to Twitter interface pages that appear as readable [blockable] hrefs.) The trending/follow box filters on the other hand use the Aria attributes, so if you read Twitter in a language other than English, those probably won't work.
I actually learned a lot about CSS selectors by making these rules, so maybe you will learn something useful as well if I walk you through them. Let's try building up the "views" selector from scratch; it's the most complicated one, and the others are just built out of its primitives.
Here's the simplest possible version of the "views" blocker:
twitter.com##a[href$="/analytics"]
This is simple enough to be readable: The filter only applies on twitter.com (and subdomains). You're blocking "a" tags (links). You're only blocking a tags with an href attribute matching a particular URL. If we knew the exact URL, say we were blocking a link to the verified tab, we could just say href="/notifications/verified" between the square brackets. In the case of the analytics links it's a different URL per tweet, so we have to use the dollar sign, which is a substring matching selector. It just means "match hrefs ending in "/analytics". Easy enough!
This version isn't good enough, though. It deletes the link, and the "N views" text within it, but it leaves a huge blank space where the text used to be. This is ugly, and doesn't restore your muscle memory if you got used to clicking on the "reply" button where the analytics button used to be. So we can do a little better:
twitter.com##div:has(>a[href$="/analytics"])
Now we're no longer blocking the <a> tag. We're blocking the div one level up, which is what creates the margins around the tag. We do this by applying a :has selector, which places a condition on the div that it must contain among its descendants the selector within the parenthesis. (The :has selector is actually experimental, but in my testing uBlock Origins supports it, even on Firefox which doesn't yet support it in regular HTML.) The > just inside the parenthesis is very important; it means "is an immediate child of". Without the >, this rule will block any div that contains a link to an /analytics URL anywhere within it, in other words, applying such a rule to Twitter.com will delete the entire website. Although in my opinion this is a good idea, it is not what we set out to do.
Even with the >, we're not done yet. On testing the filter version above, I quickly discovered that the ⋯ menu next to every tweet no longer functioned! This is because the menu is in fact a div, and one of the menu items in that div is a link to the tweet's /analytics page. So we amend the a tag we're looking for with a :not selector, ensuring it doesn't have the Aria "role" attribute designating it as a menu item, and we're done:
twitter.com##div:has(>a[href$="/analytics"]:not([role="menuitem"]))
Some interesting facts
That "menuitem" role brings us to the interesting fact I promised earlier. So the "N views" counter links you to the tweet analytics page. But it turns out there was already a link to the tweet analytics page in the side menu. And at some point they also added a separate full-line "View Tweet Analytics" link under some posts.
So this means with the new changes, if you click on a tweet you yourself made, Twitter links you to the analytics page for that tweet in three separate places.
This is… weird. This could mean Twitter has such a compelling business case for users accessing their reach metrics that they really do need to provide multiple links to that page right next to each other in case the user missed the first one, devoting more space to linking to this single page than all other post metadata combined (or for that matter, or all user-safety features combined), but… I don't think so. I think that either whoever designed and/or mandated this change (we know who mandated this change) simply didn't realize that menu item was there, or else the normal processes for QAing and design-reviewing the change were not applied to this change (either because a schedule was mandated that did not leave time for quality review, or because the team that would normally look at a change and point out "there's a second link to the same webpage right next to the first" has been depopulated). Or maybe both these things happened.
One piece of data suggesting that the "N views" changes did not have normal quality processes applied to it is the Android release. Perhaps you don't use Android, or maybe (even better) you don't use Twitter. So you may not know that the Android Twitter app update that added support for the "N views" also changed the text selection color to black. Everywhere in the app. Selections now look like redaction bars.
I don't know if this is happening to everyone or if it's somehow configuration-linked¹, but I'm seeing it on Android 12 and I spoke to someone who's seeing it on Android 13 (the newest) on a Pixel phone (the Google official phone) with GBoard (the standard keyboard). Switching to dark mode does not save you; in dark mode the selection color switches to white, to match the text. The range of affected configurations is wide enough a QA process should have caught this.
But I don't think the QA process exists at Twitter anymore. The surest sign of this is actually not that the Android "N views" update contained a bug, but that the "N views" update happened at all. For quite a lot of years, the trend in the Twitter Android app has been that new features show up only weeks or months after the iPhone app. The Android team at Twitter appears to historically be smaller, or maybe they just had a longer release process to test the many Android configurations. Historically this was actually kind of nice, as an Android user, because (1) by the time we got the features, the wrinkles had been ironed out and (2) even pre-Musk nearly every feature Twitter's added to the site in the last decade has made it worse, so who wants them anyway.
However this update did not wait for the wrinkles to iron out. The update landed on iOS and Android the same week, close enough they may have been submitted simultaneously, and not long after they hit the website. We can assume Musk has not expanded the Android team since taking over Twitter, so this sudden change in an established release cadence could mean that standard release processes were bypassed in the case of this "views" change, and the fact that a strange and embarrassingly "obvious" bug like text selection no longer working got pushed to the app store seems to confirm this theory. Making formal release processes and sticking to them is critical to getting good results from your quality team. I said QA should have caught this bug and QA probably did catch this bug; QA probably filed this bug at roughly the same time the build was submitted to the Google Play store, which is to say, 20 minutes after it was sent to QA.
Anyway. Twitter isn't a very good website. Twitter has not been a good website for a long time, and Twitter is only getting worse now. It is getting worse both because the new owner is a weird alt-right bigot but also because the new owner has bad approaches to engineering management. Twitter is trying to push you out. If you haven't already, I think you should let it.
︎¹ You can make the bug worse if you're using SwiftKey, because SwiftKey does a gentle, subtle animation every time it autocompletes a word where the autocompleted word briefly flashes a highlight in the selection color, but since Twitter Android now uses black as the selection color, typing a sentence in Twitter Android now feels like banging nails into your eyeballs. I no longer have Twitter Android on my phone.
EDIT: Added a Twitter Blue blocker to the filter list at the top.
