Repository navigation
fix(editor): highlight code blocks in editors - #2606
Conversation
🦋 Changeset detectedLatest commit: 0d437fc The changes in this PR will be included in the next version bump. This PR includes changesets to release 16 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Scope checkThis PR changes 957 lines across 17 files. Large PRs are harder to review and more likely to be closed without review. If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs. See CONTRIBUTING.md for contribution guidelines. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
docs | 463b827 | Aug 27 2026, 03:20 PM |
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/auth-atproto
@emdash-cms/blocks
@emdash-cms/cloudflare
@emdash-cms/contentful-to-portable-text
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/plugin-cli
@emdash-cms/plugin-types
@emdash-cms/registry-client
@emdash-cms/registry-lexicons
@emdash-cms/registry-moderation
@emdash-cms/registry-verification
@emdash-cms/sandbox-workerd
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-field-kit
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | e2655b3 | Aug 26 2026, 10:08 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-do | e2655b3 | Aug 26 2026, 10:06 AM |
Overlapping PRsThis PR modifies files that are also changed by other open PRs:
This may cause merge conflicts or duplicated work. A maintainer will coordinate. |
There was a problem hiding this comment.
This is the right change for issue #2361. Swapping the plain TipTap codeBlock node for @tiptap/extension-code-block-lowlight with a bounded common + dockerfile grammar set, a plaintext fallback, and scoped CSS variables hits the approved design: supported languages are highlighted in both editors, unsupported strings round-trip as plain text, and the public Code.astro renderer is untouched. The tests cover the important boundary (token spans, plain fallback, language changes, non-string language coercion) and the changeset/packages are appropriate.
I checked the changed source files, the converter tests, the E2E spec, the public code-block component, the catalog/package changes, and the admin theme provider. The only real issue I found is an AGENTS.md convention violation: the new Lowlight instances are module-scope singletons rather than living on globalThis, which can duplicate the heavy grammar map across Vite SSR chunks. Everything else looks solid. Verdict: comment.
There was a problem hiding this comment.
This is the right fix for issue #2361. Swapping the plain TipTap codeBlock node for @tiptap/extension-code-block-lowlight with a bounded common + dockerfile grammar set, a plaintext fallback, and scoped CSS variables matches the approved design: supported languages are highlighted in both the admin and inline visual editors, unsupported strings round-trip as plain text, and the public Code.astro renderer is untouched.
I re-checked the changed source files, the converter tests, the E2E spec, the public code-block component, the package/catalog changes, and the admin/inline theme styles. The only real issue from the previous review — the Lowlight instances being module-scope singletons rather than living on globalThis, which could duplicate the heavy grammar map across Vite SSR chunks — has been fixed in both packages/admin/src/components/editor/CodeBlockNode.tsx and packages/core/src/components/inline-code-block.tsx. Both now use a Symbol.for key on globalThis per AGENTS.md.
Other notable pieces look solid:
- The non-string language guard is applied consistently at both Portable Text-to-ProseMirror boundaries (
PortableTextEditor.tsxandInlinePortableTextEditor.tsx), so malformed stored values becomenullinstead of crashing decoration setup. - The
editorLowlightfacade correctly guardshighlightagainst unregistered languages and replaceshighlightAutowith a plain-text path, preserving the "no auto-detect" product decision. - Tests cover the important boundaries: token spans for supported grammars, plain fallback for
plaintext/unsupported/invalid languages, language-change updates, and storage integrity. - The inline editor CSS is scoped to
.emdash-inline-code-block/.emdash-code-block, exposes the documented override variables with system light/dark fallbacks, and uses RTL-safe logical positioning for the language chip. - The public page E2E asserts that
Code.astrostill emits onlylanguage-{id}classes and nohljs-*markup.
No remaining blocking or convention issues. LGTM.
03a8e27 to
43f23ab
Compare
43f23ab to
e2655b3
Compare
e2655b3 to
463b827
Compare
What does this PR do?
Fixes code blocks in the admin and inline visual editors so supported languages are syntax-highlighted on borderless light and dark surfaces. Unsupported language values continue to round-trip safely and render as plain text.
This is the bottom pull request in native stack #2607. The controls and visual-polish follow-up is #2603.
Closes #2361
Type of change
Checklist
pnpm typecheckpasses — verified for the affected admin and core packagespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been run.changeset/bright-code-blocks.mdAI-generated code disclosure
Screenshots / test output