Skip to content

fix: noHighlightRe now wins over languageDetectRe - #4465

Open
MsfPablo wants to merge 1 commit into
highlightjs:mainfrom
MsfPablo:fix-nohighlight-wins-over-langdetect
Open

fix: noHighlightRe now wins over languageDetectRe#4465
MsfPablo wants to merge 1 commit into
highlightjs:mainfrom
MsfPablo:fix-nohighlight-wins-over-langdetect

Conversation

@MsfPablo

@MsfPablo MsfPablo commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Closes #3700\n\nWhen a code block carries both a matching language-* / lang-* class and an explicit no-highlight / nohighlight class, the exclusion now takes precedence over language detection.\n\nChanges:\n- blockLanguage checks shouldNotHighlight before running languageDetectRe.\n- Added a test fixture + case covering the mixed-class scenario.\n\nVerified with:\n\n\nnpm run build\nnpm test\nnpm run lint\n\n\nNote: this change was prepared with assistance from Claude (Anthropic).

When a block carries both a matching language-* class and an explicit no-highlight/nohighlight class, the exclusion now takes precedence over language detection.

Closes highlightjs#3700
@joshgoebel

Copy link
Copy Markdown
Member

So I think this needs to wait for v12... this is a breaking change, yes? In that it could cause existing website to LOSE highlighting in cases where noHighlight would suddenly win - where before it would lose. Yes?

@MsfPablo

MsfPablo commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Yes — confirmed breaking, in exactly the direction you describe.

The change only affects blocks carrying both a matching language-*/lang-* class and a no-highlight/nohighlight class. For those:

  • Before: inheritSearchParams did .find(c => shouldNotHighlight(c) || getLanguage(c)), which returns the first class matching either predicate. With class="language-js no-highlight", language-js is checked first — shouldNotHighlight("language-js") is false (the default noHighlightRe is /^(no-?highlight)$/i, which does not match language-*), but getLanguage("language-js") is truthy — so the block was highlighted as JS, and the no-highlight class was effectively ignored.
  • After: the separate shouldNotHighlight pass scans all classes first, finds no-highlight, and returns no-highlight — so the same block is no longer highlighted.

So a site with class="language-js no-highlight" (or any class list where both predicates match) goes from "highlighted as JS" → "not highlighted." That is a loss of highlighting for those blocks, hence breaking.

The narrow scope is worth noting: a lone no-highlight (no matching language-* alongside it) was already respected before and after — the breakage is confined to the "both classes present" edge case from #3700. Which is exactly the behavior #3700 asks for (block list overrides allow list), and as you noted there, it is a breaking change.

Given that, I agree this should wait for v12 rather than land on v11. Happy to either keep this PR open to retarget onto a v12 branch when that work starts, or close it for now and reopen at v12 — your call on which is less noise for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

noHighlightRe should win out over languageDetectRe

3 participants