Skip to content

feat: syntax-highlight blog post code blocks at SSR#898

Merged
vivek7405 merged 3 commits into
mainfrom
feat/syntax-highlight-blog-code
Jul 10, 2026
Merged

feat: syntax-highlight blog post code blocks at SSR#898
vivek7405 merged 3 commits into
mainfrom
feat/syntax-highlight-blog-code

Conversation

@vivek7405

Copy link
Copy Markdown
Collaborator

Closes #897

Blog code fences rendered monochrome. This highlights them at SSR (zero client JS) by reusing the canonical tokenizer in website/lib/highlight.ts, the same token classes the home page and @webjsdev/ui docs use, so colors match across every WebJs surface.

What changed

  • website/lib/highlight.ts: new highlightToHtml(code) string emitter (reuses the existing tokenize() + CLASS map; HTML-escapes token text).
  • website/modules/blog/utils/render-post.ts: JS/TS fences render highlighted spans; sh/plain fences stay escaped text.
  • Token color CSS (.t-*, light + dark) promoted from the inline app/page.ts block to global public/input.css so the blog route inherits it. Home page still loads the same palette from the global sheet.

Test plan

  • Unit: highlightToHtml spans + escaping of <, &, backticks
  • Unit: render-post ts fence highlights, sh fence stays plain
  • Visual: /blog/ code blocks colored; home page unchanged
  • Self-review loop clean

Draft while I add tests and self-review.

@vivek7405 vivek7405 self-assigned this Jul 10, 2026
@vivek7405

Copy link
Copy Markdown
Collaborator Author

Review: bare-fence highlighting bug, fixed

First self-review round caught a real one. The highlighted-language set included '' (empty language), so a bare ```` fence got run through the JS tokenizer. Blog posts use bare fences for command output (the-naming-saga has npm error text; the new JS-concepts post has a serializer probe-output block), and JS-tokenizing that mis-colors words like `Forbidden` and `403`.

Fixed in 1cc566a: bare and unknown-language fences stay plain escaped text; only ts/tsx/js/jsx/javascript/typescript highlight, matched case-insensitively. Added tests pinning a bare fence to plain output (the counterfactual that would have caught this) and a case-insensitive lang. Verified live: the-naming-saga now renders 0 token spans, the JS-concepts post keeps its ts fences colored but leaves the probe-output block plain.

@vivek7405

Copy link
Copy Markdown
Collaborator Author

Review: second round clean

Rendered all 42 blog posts through the renderer: zero tokenizer errors. The language gate holds. Across the corpus there are 144 bare fences and 14 sh plus a few json/jsonc/html fences that all stay plain, and 94 ts / 5 js / 1 tsx fences that highlight. Nothing else to fix.

@vivek7405 vivek7405 marked this pull request as ready for review July 10, 2026 10:16
@vivek7405 vivek7405 merged commit 37b6433 into main Jul 10, 2026
10 checks passed
@vivek7405 vivek7405 deleted the feat/syntax-highlight-blog-code branch July 10, 2026 10:16
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.

Syntax-highlight blog post code blocks (SSR, match site tokenizer)

1 participant