gradio
3676c45a - Publish the `Prism` global before its grammars load (fixes docs pages 500ing) (#13692)

Commit
94 days ago
Publish the `Prism` global before its grammars load (fixes docs pages 500ing) (#13692) * Publish the Prism global before its grammars load Every https://gradio.app/docs/* page rendered for a moment and then replaced itself with "500 Internal Error", because hydration threw `ReferenceError: Prism is not defined` (#13677). `prismjs/components/*` and `prism-svelte` are side-effect scripts: each does `Prism.languages.x = ...` against a bare global and declares no imports of its own, so nothing in the module graph orders them after prismjs. As *static* imports the bundler is free to hoist them into a chunk that evaluates before the `globalThis.Prism = Prism` statement that was supposed to precede them — and rolldown compounds it by emitting prismjs as a lazily-invoked CommonJS factory, so importing it does not initialise it either. The live chunk shows exactly that: prismjs's factory closes and `Prism.languages.python={...}` runs on the very next statement, with the global never assigned anywhere in the file. The grammars in that chunk are python and typescript only, which identifies the source as ParamViewer — rendered on every docs page — rather than the website's own highlighter. `js/_website/src/lib/prism.ts` had the same defect though, and it was live too: in the built html-gallery chunk its grammars sat ~10kB ahead of its global assignment. Dynamic imports are not hoisted, so both now assign the global first and await the grammars after. ParamViewer gates on a promise (component init is sync, and `highlight` already fell back to plain text) while prism.ts awaits at module scope, keeping `highlight()` synchronous for the server `load` functions that render the guides and changelog. Verified against a real `VERCEL=1 vite build` of the website. Before: the build reproduces the failing chunk byte-for-byte (D3k0kEOB.js, 22248 bytes, grammars at offset 18830, no global). After: that chunk is gone, and every grammar-bearing chunk is lazy-only with no static importer, so none can execute ahead of the global. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Register the Prism grammars before ParamViewer renders Publishing the global first stopped the `ReferenceError`, but the docs pages still came out unhighlighted on a hard load, as @hysts found on the preview: every parameter type rendered as plain text and only recovered after navigating away and back. prismjs schedules its own `highlightAll()` on a `requestAnimationFrame` as soon as it loads. The grammar chunks are dynamic imports, so that pass runs before they arrive, and `highlightElement` with no grammar does `element.innerHTML = encode(element.textContent)` — wiping the server's highlighting *and* the hydration comments the `{@html}` blocks claimed during hydration. The derived does recompute once the grammars land, but it repaints into nodes that are no longer in the document, so the page stays plain. Reproduced against the real component (highlighted SSR markup as served by the preview, hydrate, prism's auto pass, then the grammars): before, the type ends as `value: str | Callable | None`; after, the token spans survive. So don't need a second paint: await the grammars in `<script module>` instead of gating a `$derived` on them. The component cannot render until they are registered, so the client's first render agrees with the server's. The `try` also stops a failed chunk from becoming an unhandled rejection — `highlight` already falls back to plain text without a grammar. This costs one round trip in front of hydration, since dynamic imports are not preloaded; client-side navigation is unaffected as the module evaluates once. Also drops `js/_website/vite-plugin-patch-paramviewer.ts`, dead since the default import: its first replacement only matched `import * as Prism`, and its second duplicates the guard already in `highlight`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Author
Parents
Loading