Skip to main content

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

  • formatter is the single source of truth for the language
  • CodeBlock and useLumis() are client exports from @lumis-sh/react
  • renderCodeBlock() 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()
  • CodeBlock and useLumis() re-highlight when children, formatter, or highlighter changes