Skip to content

fix(docs): highlight code blocks after client-side navigation (#3287)#3288

Open
MFA-G wants to merge 2 commits into
HeyPuter:mainfrom
MFA-G:fix/docs-client-nav-code-highlight
Open

fix(docs): highlight code blocks after client-side navigation (#3287)#3288
MFA-G wants to merge 2 commits into
HeyPuter:mainfrom
MFA-G:fix/docs-client-nav-code-highlight

Conversation

@MFA-G

@MFA-G MFA-G commented Jun 23, 2026

Copy link
Copy Markdown

Summary

Fixes #3287 — code highlighting is missing on the docs site after client-side navigation (e.g. clicking Deployments in the sidebar). The code only gets styled after a hard refresh.

Root cause

The docs use two different code paths to run highlight.js, and they target different selectors:

  • Full page load runs an inline hljs.highlightAll() (injected in build.js). highlightAll() uses highlight.js's default pre code selector, so it highlights every fenced block — including blocks written without a language tag.
  • Client-side navigation swaps .docs-content and fires a pathchange event. The pathchange handler in example.js highlighted only code[class^="language"].

Markdown fenced blocks without a language hint render as bare <pre><code> (no language-* class), so they matched on full load but were skipped after in-app navigation — exactly the symptom in the issue.

On the Deployments page there are 3 pre code blocks but only 1 carries a language- class, so 2 of 3 blocks stayed unstyled after client-side nav.

Fix

Align the pathchange handler with highlightAll() by selecting pre code, and skip blocks highlight.js has already processed (data-highlighted="yes") so repeated pathchange events stay idempotent and don't log highlight.js's "Element previously highlighted" warning.

-    // highlight code
-    $('code[class^=\'language\']').each(function () {
-        var $this = $(this);
-        if ( $this.attr('data-highlighted') === 'yes' ) {
-            $this.removeAttr('data-highlighted');
-        }
-        else {
-            try {
-                hljs.configure({ ignoreUnescapedHTML: true });
-                hljs.highlightElement(this);
-            } catch (e) { console.error('Error: Failed to highlight.', e); }
-        }
-    });
+    $('pre code').each(function () {
+        if ( $(this).attr('data-highlighted') === 'yes' ) return;
+        try {
+            hljs.configure({ ignoreUnescapedHTML: true });
+            hljs.highlightElement(this);
+        } catch (e) { console.error('Error: Failed to highlight.', e); }
+    });

Testing

  • npm run build in src/docs succeeds.
  • Reproduced the bug and verified the fix with a jsdom harness driving the built bundle: starting from a code-free page and simulating a pathchange navigation to the Deployments page, highlighted pre code blocks went from 0 → 3 of 3. Pre-fix the same flow highlighted only 1 of 3.
  • Confirmed the pass is idempotent — triggering pathchange again leaves all 3 blocks highlighted with no re-processing.

Scoped to a single docs file; no behavior change for blocks that already carried a language class.

The docs site highlights code on full page load via an inline
hljs.highlightAll(), which targets the 'pre code' selector and so
highlights every fenced block, including those without a language tag.

The client-side navigation path (pathchange handler) instead selected
only code[class^="language"], so fenced blocks written without a
language hint were left unhighlighted after in-app navigation while
appearing correctly on a hard reload.

Align the pathchange handler with highlightAll() by selecting 'pre code'
and skipping blocks hljs has already processed (data-highlighted=yes),
keeping the pass idempotent across repeated pathchange events.

Fixes HeyPuter#3287
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@xsourabhsharma

Copy link
Copy Markdown
Contributor

Fix is correct selector change to pre code aligns with hljs.highlightAll() and the idempotency guard is clean.

Two nits:

  • Move hljs.configure({ ignoreUnescapedHTML: true }) outside the loop it's a global config, no need to call it on every element.
  • Consider scoping $('pre code') to $('.docs-content pre code') to avoid touching blocks outside the docs area on pathchange.

Address review nits on the pathchange highlight pass:
- Move hljs.configure({ ignoreUnescapedHTML: true }) out of the per-element
  loop since it is global config and only needs to run once.
- Scope the selector to '.docs-content pre code' so the re-highlight pass
  only touches the swapped-in docs body and leaves code blocks elsewhere
  on the page untouched.
@MFA-G

MFA-G commented Jun 24, 2026

Copy link
Copy Markdown
Author

Thanks for the review @xsourabhsharma — both addressed in 2e2d91b:

  • Moved hljs.configure({ ignoreUnescapedHTML: true }) out of the .each() loop so the global config runs once per pathchange instead of per element.
  • Scoped the selector to .docs-content pre code so the re-highlight pass only touches the swapped-in docs body and leaves any code blocks elsewhere on the page untouched.

node --check passes on the file.

@xsourabhsharma

Copy link
Copy Markdown
Contributor

@MFA-G could you plz sign the CLA?

@reynaldichernando

Copy link
Copy Markdown
Member

thanks @MFA-G @xsourabhsharma , i reviewed this, and it's ready to merge
@MFA-G could you help sign the CLA? it's standard for contributions

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing code highlighting in docs, when navigating client side

4 participants