本页还没有译文
本页 24 段还没译成Deutsch,下面显示的是英文原文。SSR and Client Rendering
还没翻译译自英文(tanstack.com)本页 24 段都还没译
SSR and Client Rendering
The recommended architecture is hydrated SSR: highlight the initial document on the server, then reuse the same synchronous registry for client navigations and dynamic content.
Isomorphic module
// src/lib/highlight.ts
import { createHighlighter } from '@tanstack/highlight/core'
import { css } from '@tanstack/highlight/languages/css'
import { html } from '@tanstack/highlight/languages/html'
import { js } from '@tanstack/highlight/languages/js'
import { json } from '@tanstack/highlight/languages/json'
import { shell } from '@tanstack/highlight/languages/shell'
import { ts } from '@tanstack/highlight/languages/ts'
import { tsx } from '@tanstack/highlight/languages/tsx'
export const highlighter = createHighlighter({
languages: [css, html, js, json, shell, ts, tsx],
})Do not put server-only imports in this module. The highlighter itself needs none.
Server path
Highlight before serializing or streaming the code block:
const data = highlighter.renderCodeBlockData({
code,
lang,
title,
decorations,
})Send or render data.htmlMarkup. Keep data.copyText for a copy button.
Hydration
Server-rendered code does not need to be highlighted again. It is already static HTML controlled by CSS.
Use the client highlighter only for code introduced after hydration:
- Client-side route content not included in the initial payload
- Live Markdown previews
- Interactive examples that change source
- User-selected language variants
Determinism
Server and client output match when all of these match:
- Source string
- Language registrations and order
- Language option
- Decorations and line-number option
- Package version
Themes do not affect highlighted markup.
Avoid hydration mismatches
- Export one registry module used by both paths.
- Do not conditionally register languages with
windowchecks. - Normalize Markdown fence metadata before rendering on both paths.
- Do not highlight trimmed code on one path and untrimmed code on the other.
renderCodeBlockData() and renderCodeFence() trim trailing block whitespace consistently for copy/render workflows. highlight() preserves its input exactly.
Caching
The highlighter is fast enough for normal docs pages without a cache. For large static builds, cache by package version, language, source, and decoration options if build time becomes material.
Do not cache theme variants separately. They share the same HTML.
Why no worker?
The docs-sized path is synchronous and usually much cheaper than worker startup and message serialization. A worker is reasonable only for unusually large interactive inputs, which is outside the primary use case.