import { SyntaxHighlightingSample } from "@/components/docs/samples/syntax-highlighting";
Syntax highlighting is not enabled in markdown by default.
`assistant-ui` provides two options for syntax highlighting: - **react-shiki** (recommended for performance & dynamic language support) - **react-syntax-highlighter** (legacy - Prism or Highlight.js based)react-shiki#
Add shiki-highlighter#
<InstallCommand shadcn={["shiki-highlighter"]} />
This adds a /components/assistant-ui/shiki-highlighter.tsx file to your project and
installs the react-shiki dependency. The highlighter can be customized by editing
the config in the shiki-highlighter.tsx file.
Add it to defaultComponents in markdown-text.tsx#
import { SyntaxHighlighter } from "./shiki-highlighter";
export const defaultComponents = memoizeMarkdownComponents({
SyntaxHighlighter: SyntaxHighlighter, // [!code ++]
h1: /* ... */,
// ...other elements...
});
Options#
See react-shiki documentation for all available options.
Key options:
theme- Shiki theme or multi-theme object ({ light, dark, ... })language- Language for highlighting (default:"text")defaultColor- Default color mode (string | false, e.g.light-dark())delay- Delay between highlights, useful for streaming (default:0)customLanguages- Custom languages to preload for dynamic supportcodeToHastOptions- All other options accepted by Shiki'scodeToHast
Dual/multi theme support#
To use multiple themes, pass a theme object:
<ShikiHighlighter
/* ... */
theme={{
light: "github-light",
dark: "github-dark",
}}
defaultColor="light-dark()"
/* ... */
Note: The
shiki-highlightercomponent setsdefaultColor="light-dark()"automatically.
Only set this manually if usingShikiHighlighterdirectly.
With defaultColor="light-dark()", theme switching is automatic based on your site's color-scheme.
No custom Shiki CSS overrides are required.
Set color-scheme on your app root:
System-based (follows OS/browser preference):
:root {
color-scheme: light dark;
}
Class-based theme switching:
:root {
color-scheme: light;
}
:root.dark {
color-scheme: dark;
}
If you need broader support for older browsers, you can still use the manual CSS-variable switching approach from the Shiki dual-theme docs.
For more information:
Bundle Optimization#
By default, react-shiki includes the full Shiki bundle, which contains all supported languages and themes.
To reduce bundle size, you can use the web bundle by changing the import to react-shiki/web, to include a smaller bundle of web related languages:
import ShikiHighlighter, { type ShikiHighlighterProps } from "react-shiki/web";
Custom Bundles#
For strict bundle size control, react-shiki also supports custom bundles created using createHighlighterCore from react-shiki/core (re-exported from Shiki):
import { createHighlighterCore, createOnigurumaEngine } from "react-shiki/core"; // [!code ++]
// Create the highlighter
// Use dynamic imports to load languages and themes on client on demand
const customHighlighter = await createHighlighterCore({
themes: [import("@shikijs/themes/nord")],
langs: [
import("@shikijs/langs/javascript"),
import("@shikijs/langs/typescript"),
],
engine: createOnigurumaEngine(import("shiki/wasm")),
});
// Then pass it to the highlighter prop
<SyntaxHighlighter
{...props}
language={language}
theme={theme}
highlighter={customHighlighter} // [!code ++]
/>;
react-syntax-highlighter#
This option may be removed in a future release. Consider using [react-shiki](#react-shiki) instead.Add syntax-highlighter#
<InstallCommand shadcn={["syntax-highlighter"]} />
Adds a `/components/assistant-ui/syntax-highlighter.tsx` file to your project and installs the `react-syntax-highlighter` dependency.
Add it to defaultComponents in markdown-text.tsx#
import { SyntaxHighlighter } from "./syntax-highlighter";
export const defaultComponents = memoizeMarkdownComponents({
SyntaxHighlighter: SyntaxHighlighter, // [!code ++]
h1: /* ... */,
// ...other elements...
});
Options#
Supports all options from react-syntax-highlighter.
Bundle Optimization#
By default, the syntax highlighter uses a light build that only includes languages you register. To include all languages:
import { makePrismAsyncSyntaxHighlighter } from "@assistant-ui/react-syntax-highlighter/full";