From db9e01d2d4351250233c76b1818b7d96a35dd4c7 Mon Sep 17 00:00:00 2001 From: Steven Hall Date: Fri, 18 Jul 2025 18:21:24 +0100 Subject: [PATCH] Always perform code highlighting server-side. --- .../CodeBlock/ClientCodeBlock.tsx | 23 ++++++++++--------- .../DocumentView/CodeBlock/server-actions.ts | 16 +++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 packages/gitbook/src/components/DocumentView/CodeBlock/server-actions.ts diff --git a/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx b/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx index ede23ee1d..fe76cc66d 100644 --- a/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx +++ b/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx @@ -10,6 +10,7 @@ import type { BlockProps } from '../Block'; import { CodeBlockRenderer } from './CodeBlockRenderer'; import type { HighlightLine, RenderedInline } from './highlight'; import { plainHighlight } from './plain-highlight'; +import { highlightCodeBlock } from './server-actions'; type ClientBlockProps = Pick, 'block' | 'style'> & { inlines: RenderedInline[]; @@ -28,10 +29,7 @@ export function ClientCodeBlock(props: ClientBlockProps) { const [lines, setLines] = useState(null); const [highlighting, setHighlighting] = useState(false); - // Preload the highlighter when the block is mounted. - useEffect(() => { - import('./highlight').then(({ preloadHighlight }) => preloadHighlight(block)); - }, [block]); + // Note: Preloading is not needed since we're using server actions for highlighting // When user scrolls, we need to wait for the scroll to finish before running the highlight const isScrollingRef = useRef(false); @@ -79,15 +77,18 @@ export function ClientCodeBlock(props: ClientBlockProps) { if (typeof window !== 'undefined') { setHighlighting(true); - import('./highlight').then(({ highlight }) => { - highlight(block, inlines).then((lines) => { - if (cancelled) { - return; - } + highlightCodeBlock(block, inlines).then((lines) => { + if (cancelled) { + return; + } - setLines(lines); + setLines(lines); + setHighlighting(false); + }).catch((error) => { + console.error('Failed to highlight code block:', error); + if (!cancelled) { setHighlighting(false); - }); + } }); } diff --git a/packages/gitbook/src/components/DocumentView/CodeBlock/server-actions.ts b/packages/gitbook/src/components/DocumentView/CodeBlock/server-actions.ts new file mode 100644 index 000000000..fe4ba3796 --- /dev/null +++ b/packages/gitbook/src/components/DocumentView/CodeBlock/server-actions.ts @@ -0,0 +1,16 @@ +'use server'; + +import type { DocumentBlockCode } from '@gitbook/api'; +import type { HighlightLine, RenderedInline } from './highlight'; +import { highlight } from './highlight'; + +/** + * Server action to highlight code blocks. + * This ensures highlighting always happens on the server, avoiding browser issues. + */ +export async function highlightCodeBlock( + block: DocumentBlockCode, + inlines: RenderedInline[] +): Promise { + return await highlight(block, inlines); +}