Nescroll docs
v1.0.0
Get help
● Use · How filters work

Filters
and how to fix one when a site changes.

The sites change their pages often. When a filter stops working, you fix it by changing a CSS selector, a label text or a redirect, either in Platform.swift (next app version) or in a remote rules.json (no release needed).

Platform.swiftResources/page.jsSafari Web Inspector

01Three ways a filter removes something

A filter (struct Filter in Platform.swift) can use any of these:

PartWhat it doesWhere it runs
redirectsA regular expression over the page path and query, and a target path. /shorts/abc becomes /watch?v=abc. $1 to $9 insert captured groups.Both in Swift when a page loads (PageConfig.redirect in Browser.swift) and in JavaScript when the site changes the address without a reload (page.js, checked every 400 ms and on every history change).
selectorsCSS selectors that are hidden with display: none !important. html[data-nr-path^="/reel/"] … limits a selector to one page, because page.js writes the current path into data-nr-path.page.js, as a style sheet.
labelsExact texts, such as "Sponsored". A feed item that shows one of them is hidden. Max 40 characters.page.js, re-checked 300 ms after the page changes.

Built-in filters may also run extra JavaScript (script); YouTube's ad filter uses it to mute and skip video ads. Remote rules cannot add scripts.

How a label finds "the post": if the site has an item selector (Platform.itemSelector, for example article on Instagram), the closest match is hidden. Otherwise the script climbs to the first parent at least 240 points tall. It never hides an element taller than 1.5 screens or one that contains navigation, a header, a text field or an editable area.

02Built-in filters

SiteFilter (id)Uses
InstagramReels (instagram.reels)Redirects /reels/ to the inbox and a reels link to the single reel; hides Reels links and the "more reels" area
Explore (instagram.explore)Redirects /explore/ to search; hides the picks grid under search
Suggested posts (instagram.suggested)Labels "Suggested for you" and similar
Ads (instagram.ads)Label "Sponsored"
YouTubeShorts (youtube.shorts)Redirects /shorts to Subscriptions and a short to the normal player; hides Shorts shelves and the Shorts tab
Home feed (youtube.home)Redirects / to Subscriptions; hides the Home tab button
Up next (youtube.upnext)Hides related videos, autoplay toggle and end screens
Ads (youtube.ads)Hides promoted items; script mutes and skips video ads
FacebookReels (facebook.reels)Redirect, Reels links, label "Reels and short videos"
Video tab (facebook.video)Redirects the video feed home; a shared video (?v=) still plays
Suggested posts (facebook.suggested)Labels "Suggested for you", "People you may know" and similar
Ads (facebook.ads)Label "Sponsored"
Marketplace (facebook.marketplace)Redirect and Marketplace links

The ids are stored in user defaults as filter.<id>. Do not rename an id unless you accept that users' on/off choices for it reset.

03Find the new markup with Safari

The web views are inspectable (webView.isInspectable = true in Browser.swift), so you can look inside a tab from your Mac:

  1. Turn on the Develop menu in Safari on the Mac: Safari → Settings → Advanced → "Show features for web developers".
  2. On the iPhone: Settings → Apps → Safari → Advanced → Web Inspector on. (In the Simulator nothing is needed.)
  3. Run your app, open the tab with the problem, then in Safari on the Mac choose Develop → your device → the page.
  4. Inspect the element that should be hidden. Note a stable tag name, attribute or link (a[href^="/shorts"] is better than a generated class like x1n2onr6).
  5. Test the selector in the console: document.querySelectorAll('your-selector').length should be more than 0 on the page and 0 where nothing should be hidden.

04Fix a filter

A section shows again (new markup): add the new selector to the filter's selectors array in Platform.swift. Keep the old one too while some users still get the old page.

Filter(
    id: "youtube.shorts", title: String(localized: "Shorts"),
    ...
    selectors: [
        "ytm-reel-shelf-renderer",
        // added after a markup change:
        "ytm-shorts-new-shelf",
    ]
)

Sponsored or suggested posts show again (new wording): add the exact text, as the site shows it, to labels. Copy it from the inspector; curly quotes and non-breaking spaces matter.

A page opens that should be redirected (new address): add a Redirect(pattern:target:). Write the pattern so that JavaScript and NSRegularExpression read it the same way (no look-behind, no named groups). Add a test case in RedirectTests and run the tests.

Something is hidden that should not be: make the selector more specific, or scope it with html[data-nr-path^="/page"].

Ship the fix in the next app version, or right away through remote rules.

05Add another site

Possible, but it means code in several places: a new case in enum Platform, its name, symbol, home, hostSuffixes, redirectHosts, itemSelector and filters, the new filter list, the strings in the String Catalog, and the case in AppConfig.platforms. Check the site's terms first (platform terms).