Syntax Highlighting
Syntax highlighting for code blocks in markdown.
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
npx shadcn@latest add "https://r.assistant-ui.com/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,
h1: /* ... */,
// ...other elements...
});
Options
Prop | Type | Default |
---|---|---|
theme | github-dark | |
language | text | |
as? | React.ElementType | pre |
className? | string | - |
style? | React.CSSProperties | - |
delay? | number | - |
customLanguages? | - | |
codeToHastOptions | {} |
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";
// 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}
/>;
For more information, see react-shiki - bundle options.
Dual/multi theme support
To use multiple theme modes, pass an object with your multi-theme configuration to the theme
prop in the ShikiHighlighter
component:
<ShikiHighlighter
/* ... */
theme={{
light: "github-light",
dark: "github-dark",
}}
/* ... */
>
To make themes responsive to your site's theme mode, add one of the following CSS snippets to your project:
/* for class based dark mode */
html.dark .shiki,
html.dark .shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
/* Optional, if you also want font styles */
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
/* for query based dark mode */
@media (prefers-color-scheme: dark) {
.shiki,
.shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
/* Optional, if you also want font styles */
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
}
For more information, see Shiki's documentation on dual and multi themes.
react-syntax-highlighter
This option may be removed in a future release. Consider using react-shiki instead.
Add syntax-highlighter
npx shadcn@latest add "https://r.assistant-ui.com/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,
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";