nhentai Language Filter

Adds quick language filters (English, Japanese, Chinese) to nhentai pages — works with SvelteKit SPA navigation

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

작성자
Snow2122
일일 설치 수
0
총 설치 수
50
평점
1 0 0
버전
1.2.0
생성일
2026-01-21
갱신일
2026-03-31
크기
12.9KB
라이선스
MIT
적용 사이트

nhentai Language Filter

Adds one-click language filter buttons to every nhentai.net listing page.


Script file nhentai Language Filter.txt
Author Snow2122
Version 1.2.0
License MIT
Updated 2026-04-01
Applies to nhentai.net

Overview

A userscript that injects English Only, Japanese Only, Chinese Only, and All filter buttons directly onto nhentai.net listing pages. Clicking a filter navigates to the matching search query using nhentai's own SPA router — no forced page reloads. Filters reappear automatically after every client-side navigation, and persist through SvelteKit's hydration re-renders.


✨ Features

Feature Description
Namespace page filters Inline filter buttons added to the sort bar on tag, artist, character, parody, group, and category pages
Search page filters Same filter buttons on search result pages — the active language is highlighted in red
Favorites page filters Compact flag buttons (🇬🇧 EN / 🇯🇵 JP / 🇨🇳 CN / 🌍 ALL) next to the random button
Homepage dropdown A 🌐 Language ▾ hover dropdown in the navigation bar for instant language-filtered browsing from the home page
SPA navigation support Filters are re-injected automatically after every SvelteKit client-side navigation
Hydration resilience A permanent MutationObserver watches the DOM and re-injects filters if SvelteKit's hydration pass wipes them
Clean navigation Filter links use nhentai's SPA router — browsing stays smooth with no full reloads
State tracking Injected elements carry a data-nhi-lang marker for reliable detection and clean removal on navigation

📄 Supported Pages

Page URL Pattern Filter Style
Home nhentai.net/ 🌐 Dropdown in nav bar
Search results nhentai.net/search?q=… Buttons in sort bar
Tag pages nhentai.net/tag/… Buttons in sort bar
Artist pages nhentai.net/artist/… Buttons in sort bar
Character pages nhentai.net/character/… Buttons in sort bar
Parody pages nhentai.net/parody/… Buttons in sort bar
Group pages nhentai.net/group/… Buttons in sort bar
Favorites nhentai.net/user/favorites/ 🚩 Flag buttons next to random

📦 Installation

Step 1 — Install a userscript manager

Manager Supported browsers
Tampermonkey Chrome, Firefox, Edge, Opera
Violentmonkey Chrome, Firefox, Edge
Greasemonkey Firefox

Step 2 — Install the script

  1. Open your userscript manager's dashboard from the browser toolbar
  2. Click "Create a new script" (or "Add new script")
  3. Delete any placeholder code the editor has pre-filled
  4. Copy the full contents of nhentai Language Filter.txt and paste it in
  5. Save with Ctrl + S or click the Save button

🖱️ Usage

Tag / artist / character / parody / group / category pages

Language filter buttons appear automatically inline with the sort bar:

[ Recent ]  Popular: today  week  all time  |  English Only  Japanese Only  Chinese Only  All

Clicking English Only on /tag/cheating/ navigates to:

/search?q=tag%3Acheating+language:english

The same filter buttons appear on that search results page, with English Only highlighted in red to show the active filter. Clicking All removes the language restriction and returns to the unfiltered tag results.


Search result pages

Filter buttons appear in the sort bar. The currently active language filter (if any) is highlighted in red.

[ Recent ]  Popular: today  week  all time  |  English Only*  Japanese Only  Chinese Only  All

* = highlighted in red


Home page

A 🌐 Language ▾ dropdown appears in the right side of the navigation bar. Hover over it to open:

🌐 Language ▾
  ┌─────────────┐
  │ 🇬🇧 English  │
  │ 🇯🇵 Japanese │
  │ 🇨🇳 Chinese  │
  │ 🌍 All       │
  └─────────────┘

Clicking a language navigates to the corresponding search page (e.g. /search?q=language:english).


Favorites page

Flag buttons appear next to the random button inside your favorites:

🎲 Random  |  🇬🇧 EN   🇯🇵 JP   🇨🇳 CN   🌍 ALL

These filter your saved favorites by language and persist through paginated browsing.


🔍 How It Works

  1. Navigation detection — The script patches history.pushState, history.replaceState, and popstate so it is notified of every SvelteKit client-side navigation.

  2. Staggered injection passes — On each navigation (and on initial load), checkAndInject() is called at six independent delays: 0 ms, 150 ms, 400 ms, 800 ms, 1500 ms, 2500 ms. These use direct setTimeout calls, not a shared debounce timer, so the MutationObserver can never cancel them.

  3. Hydration recovery — A permanent MutationObserver watches document.body for any DOM changes (80 ms debounce, independent timer). If SvelteKit's hydration wipes injected elements, the observer detects the change and immediately re-injects.

  4. Page type detectioncheckAndInject() reads window.location.pathname and calls the appropriate injector:

| Pathname pattern | Injector | Target element | |---|---|---| | /tag/, /artist/, /character/, etc. | injectNamespace() | .sort div | | /search | injectSearch() | .sort div | | /user/favorites/ | injectFavorites() | Next to #favorites-random-button | | / | injectHomepage() | .menu.right nav |

  1. State management — Every injected element has data-nhi-lang="<code>" set on it. Before injecting for a new page, all elements with this attribute from the previous page are removed. If elements for the current page are already present, the injection is skipped.

🏷️ URL Format Reference

The filter buttons generate URLs in this format:

Context Generated URL
Tag page → English /search?q=tag%3A{slug}+language:english
Tag page → All /tag/{slug}/ (original URL, no language filter)
Search page → Japanese /search?q={existing query} language:japanese
Search page → All /search?q={query without language term}
Home page → Chinese /search?q=language:chinese
Favorites → English /user/favorites/?q=language:english

The stripLanguage() helper removes any existing language:xxx term from the current query before adding the new one, so switching between languages never stacks multiple language filters.


📋 Changelog

v1.2.0 — 2026-04-01

Full SPA compatibility rewrite.

  • [ADD] SPA navigation detection — patches history.pushState / replaceState and popstate
  • [ADD] Permanent MutationObserver for hydration resilience (80 ms debounce, independent timer)
  • [ADD] onNavigate() fires injection at six independent staggered delays — the MutationObserver debounce cannot cancel them
  • [ADD] Language filter buttons on search result pages (/search?q=…) — active language highlighted in red
  • [ADD] Language filter buttons on Favorites page — compact flag buttons next to the random button
  • [ADD] data-nhi-lang marker attribute on every injected element for reliable clean-up on navigation
  • 🐛 [FIX] Filters now persist after clicking a language — the filtered search page gets its own set of filter buttons
  • 🐛 [FIX] Homepage dropdown no longer flashes and disappears — re-injected immediately after SvelteKit hydration wipes it
  • 🐛 [FIX] pathname.startsWith("/search") replaces the old regex that required a trailing slash — correctly matches /search?q=… without trailing slash
  • 🐛 [FIX] All generated filter links use /search?q=… (no trailing slash before ?) to match actual SvelteKit URL format
  • 🔄 [CHANGE] lastKey updated before the injection attempt (not only on success) — retry passes skip cleanup and go straight to injection
  • 🔄 [CHANGE] MutationObserver uses muteTimer (its own independent timer) separate from navigation schedules
  • 🔄 [CHANGE] @match https://nhentai.net/search* replaces search/* to cover URLs without trailing slash

v1.0.0 — Initial release

  • [ADD] Language filter buttons on tag, artist, character, parody, group, and category pages (injectNamespace)
  • [ADD] Homepage language dropdown in the navigation bar (injectHomepage)
  • [ADD] stripLanguage() helper removes existing language terms before applying a new filter
  • [ADD] buildSortItem() and buildSortAll() element builders for reusable sort-type divs

🙏 Credits

  • Snow2122 — Author, SPA rewrite, documentation

📜 License

Licensed under the MIT License. You are free to use, modify, and distribute this script for any purpose provided the original copyright notice is retained.


✍️ Author

Snow2122