# antisocial Reads social posts back to you without the app. Links to X, Threads, Instagram, TikTok, Bluesky and Reddit get shared constantly, and opening one means an app interstitial, a login wall, a feed you didn't ask for, and a pile of tracking. antisocial is the other half of a StopTheMadness rewrite rule: the link gets redirected here, and you get the post — the media and the words — plus a badge saying where it came from and a button to copy the original URL if you do want to go there. Built for one person, on a private network. There is **no authentication of any kind** — anything that can reach it can drive a browser through it, so put it somewhere only you can reach. It resolves posts by driving a real headless browser, logged out, exactly as if you had opened the link yourself. ## StopTheMadness rules One redirect rule per platform. The host is swapped for antisocial plus a short platform segment; the rest of the path is left alone, so the original is always recoverable and readable in your history. Replace `antisocial.example.com` with wherever you are running it. Each rule is two fields. Both are on their own line below, and neither needs any escaping — copy them straight out of this file. ```text # X /^https:\/\/(?:www\.|mobile\.)?(?:x|twitter)\.com\/(.*)$/ https://antisocial.example.com/x/$1 # Threads /^https:\/\/(?:www\.)?threads\.(?:net|com)\/(.*)$/ https://antisocial.example.com/threads/$1 # Instagram /^https:\/\/(?:www\.)?instagram\.com\/(.*)$/ https://antisocial.example.com/ig/$1 # TikTok /^https:\/\/(?:www\.|vm\.|vt\.)?tiktok\.com\/(.*)$/ https://antisocial.example.com/tiktok/$1 # Bluesky /^https:\/\/bsky\.app\/(.*)$/ https://antisocial.example.com/bsky/$1 # Reddit /^https:\/\/(?:www\.|old\.|new\.|np\.|m\.)?reddit\.com\/(.*)$/ https://antisocial.example.com/reddit/$1 # Reddit short links /^https:\/\/redd\.it\/(.*)$/ https://antisocial.example.com/reddit/$1 ``` A code block rather than a table, because a table cell cannot hold a bare `|` — it has to be written `\|`, which renders correctly and copies wrongly. The alternation in these rules is full of them, and a regex whose pipes arrive as literal pipes matches nothing and says nothing about why. So `https://x.com/user/status/123` becomes `https://antisocial.example.com/x/user/status/123`. Tracking parameters (`igsh`, `utm_*`, `share_id`, `s`, `t`, and friends) are stripped on arrival, so the URL the copy button gives back is the clean one. TikTok `vm.`/`vt.` share codes lose their subdomain in the rewrite; a single opaque path segment is recognised as a share code and rebuilt as `vm.tiktok.com//`, or `redd.it/` where it came from Reddit. A Reddit `/r//s/` share link is followed to the post it points at, and that permalink — not the opaque share code — is what the copy button hands back. `/` serves these rules with the live hostname already filled in, if you'd rather copy them from there. ## Opening the original The rules are indiscriminate, which is the point — but that catches the way back out too. Tapping "Open on Instagram" in the browser the rules are installed in redirects straight back here, so the one button meant to get you to the app is the one button that cannot. The way past it is to hand the address to a *different* browser, by its own URL scheme. `/` has a picker for which one: | Browser | macOS | iOS | | --- | --- | --- | | Chrome | `googlechromes://…` | `googlechromes://…` | | Edge | `microsoft-edge:https://…` | `microsoft-edge-https://…` | | Orion | `orion://open-url?url=…` | `orion://open-url?url=…` | | Firefox | — | `firefox://open-url?url=…` | Firefox on macOS registers no scheme, so it is not offered there; nor is Safari itself, which is the browser being escaped. The choice is kept in that browser's own `localStorage` — not a cookie and not synced, because "which browser is installed" is a fact about the device, not about you, and the phone's answer is not the Mac's. The link in the page is always the plain `https://` address, and the scheme is swapped in by the script afterwards; with JavaScript off, or with the default left alone, nothing changes. Once a browser is chosen the button says which one, because a scheme for a browser that isn't installed opens nothing at all, and a silent tap needs an explanation. The URL underneath stays selectable either way. ## How it works Every request drives a real Chromium page load. One code path, and it survives markup changes better than parsing HTML from the outside would. Each adapter layers its extraction, most structured first: 1. **The platform's own API response**, caught as it goes past during the page load. Reading the JSON a platform serves its own front end beats scraping what it renders. 2. **An inline payload** in the page — a JSON script tag, or an object buried in a bootstrap call (`src/platforms/scan.ts` pulls a balanced object out by key, including when it arrives escaped inside a JS string, which is what Instagram does). 3. **The rendered DOM** — whatever is actually on screen is real. 4. **Open Graph tags** — the floor, and enough to show something. | Platform | Loads | Reads | | --------- | ---------------------------- | --------------------------------------------------------------- | | Bluesky | the public AT Protocol API | `getPostThread`; falls back to the post page | | X | `platform.twitter.com` embed | the `cdn.syndication.twimg.com/tweet-result` response | | Instagram | `/embed/captioned/` | `shortcode_media`, then the rendered `