React
Examples:
@lumis-sh/react follows the same formatter-first API as the rest of Lumis, but splits client and server helpers.
Install
npm install @lumis-sh/react @lumis-sh/lumis @lumis-sh/themes react
Client component
Use CodeBlock when you want a drop-in React component.
Simple
import {CodeBlock} from '@lumis-sh/react'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import githubLight from '@lumis-sh/themes/github_light'
const codeString = `export function Hello() {
return <h1>Hello</h1>
}`
export function Example() {
return (
<CodeBlock formatter={htmlInline({language: 'tsx', theme: githubLight})}>
{codeString}
</CodeBlock>
)
}
Reuse one highlighter
import {CodeBlock} from '@lumis-sh/react'
import {createHighlighter} from '@lumis-sh/lumis'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import githubLight from '@lumis-sh/themes/github_light'
const highlighter = createHighlighter({languages: [bundledLanguages]})
const codeString = `export function Hello() {
return <h1>Hello</h1>
}`
export function Example() {
return (
<CodeBlock
highlighter={highlighter}
formatter={htmlInline({language: bundledLanguages.tsx, theme: githubLight})}
>
{codeString}
</CodeBlock>
)
}
If you do not pass highlighter, CodeBlock uses a shared internal highlighter. Passing your own highlighter is the better choice when you want to preload bundles or reuse one instance across many blocks.
Hook
Use useLumis() when you want to control the loading UI yourself.
import {useLumis} from '@lumis-sh/react'
import {createHighlighter} from '@lumis-sh/lumis'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import githubLight from '@lumis-sh/themes/github_light'
const highlighter = createHighlighter({languages: [bundledLanguages]})
export function Example() {
const {content, isLoading} = useLumis({
children: 'export const answer = 42',
formatter: htmlInline({language: 'typescript', theme: githubLight}),
highlighter,
})
if (isLoading) return <p>Loading syntax highlighter...</p>
return <>{content}</>
}
Server rendering
Use renderCodeBlock() from the server subpath when you need highlighted output on the server.
This is a good fit for React Server Components and Next.js App Router pages.
import {renderCodeBlock} from '@lumis-sh/react/server'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import githubLight from '@lumis-sh/themes/github_light'
const codeString = `export function Hello() {
return <h1>Hello</h1>
}`
export async function Article() {
const block = await renderCodeBlock({
children: codeString,
formatter: htmlInline({language: bundledLanguages.tsx, theme: githubLight}),
})
return <article>{block}</article>
}
Reusing one highlighter
Create one Highlighter and pass it into CodeBlock or useLumis():
import {createHighlighter} from '@lumis-sh/lumis'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
import {CodeBlock} from '@lumis-sh/react'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import githubLight from '@lumis-sh/themes/github_light'
const codeString = `export const answer = 42`
const highlighter = await createHighlighter({languages: [bundledLanguages]})
export function Example() {
return (
<CodeBlock
highlighter={highlighter}
formatter={htmlInline({language: 'tsx', theme: githubLight})}
>
{codeString}
</CodeBlock>
)
}
This is the best option when you want to preload a bundle and render many code blocks on one page.
Behavior
formatteris the single source of truth for the languageCodeBlockanduseLumis()are client exports from@lumis-sh/reactrenderCodeBlock()is a server export from@lumis-sh/react/server- the React helpers call
highlighter.loadLanguage(formatter.language)before highlighting - when the language is already loaded, Lumis reuses the cached result
- for true server-rendered highlighting, prefer
renderCodeBlock() CodeBlockanduseLumis()re-highlight whenchildren,formatter, orhighlighterchanges