Always perform code highlighting server-side.

This commit is contained in:
Steven Hall
2025-07-18 18:21:24 +01:00
parent a747080058
commit db9e01d2d4
2 changed files with 28 additions and 11 deletions
@@ -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<BlockProps<DocumentBlockCode>, 'block' | 'style'> & {
inlines: RenderedInline[];
@@ -28,10 +29,7 @@ export function ClientCodeBlock(props: ClientBlockProps) {
const [lines, setLines] = useState<null | HighlightLine[]>(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);
});
}
});
}
@@ -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<HighlightLine[]> {
return await highlight(block, inlines);
}