UserByScreenNameendpoint uses rotating query IDs — must discover from JS bundles, never hardcode- The
featureSwitchesarray near the query definition in bundles can be extracted and all set totrue - IMPORTANT: Newer API responses have moved
screen_nameOUT of thelegacyobject. Don't rely onlegacy.screen_nameexisting. Use the screen name you already know from the request parameter instead. followers_countis still inlegacybut always use fallback deep searchdescription(bio) is inlegacy.descriptionorprofile_bio.description- Bearer token is public/shared across all Twitter web clients
- CSRF token comes from
ct0cookie - Rate limit: ~1000 requests per 15-minute window; use escalating delays + 429 backoff
- Use
origFetch(saved before overridingwindow.fetch) for own API calls to avoid infinite loops
@run-at document-start+ fetch/XHR interception to capture Twitter's own API responses- Serialized queue with escalating delays (1-3s base, +1s per consecutive request, capped at 10-12s)
- Queue cancellation on DOM changes — only fetches currently visible profiles
userCacheMap stores{ followers, bio, ts }per lowercase handle- Persistent cache in
localStoragewith 7-day TTL - MutationObserver triggers
processTweets()on DOM changes scheduleReprocess()debounces re-processing when new cache entries arrive
- Tweets:
article[data-testid="tweet"] - User name:
[data-testid="User-Name"], Avatar:[data-testid^="UserAvatar-Container-"] - Three-dot menu:
[data-testid="caret"] - Back button (soft nav):
[data-testid="app-bar-back"] - Retweet button:
[data-testid="retweet"]/[data-testid="unretweet"] - Dropdown menus:
[role="menu"]→[role="menuitem"] - Tabs:
[role="tablist"]→[role="tab"] - j/k focused tweet: walk
document.activeElementup toarticle[data-testid="tweet"]