@@ -23,6 +23,7 @@ A performant client-side syntax highlighting component and hook for React, built
2323 - [ Custom Languages] ( #custom-languages )
2424 - [ Preloading Custom Languages] ( #preloading-custom-languages )
2525 - [ Custom Transformers] ( #custom-transformers )
26+ - [ Line Numbers] ( #line-numbers )
2627 - [ Integration] ( #integration )
2728 - [ Integration with react-markdown] ( #integration-with-react-markdown )
2829 - [ Handling Inline Code] ( #handling-inline-code )
@@ -44,6 +45,7 @@ A performant client-side syntax highlighting component and hook for React, built
4445- 🖥️ ` ShikiHighlighter ` component displays a language label for each code block
4546 when ` showLanguage ` is set to ` true ` (default)
4647- 🎨 Customizable styling of generated code blocks and language labels
48+ - 📏 Optional line numbers with customizable starting number and styling
4749
4850## Installation
4951
@@ -155,6 +157,8 @@ See [Shiki - RegExp Engines](https://shiki.style/guide/regex-engines) for more i
155157| ` theme ` | ` string \| object ` | ` 'github-dark' ` | Single or multi-theme configuration, built-in or custom textmate theme object |
156158| ` delay ` | ` number ` | ` 0 ` | Delay between highlights (in milliseconds) |
157159| ` customLanguages ` | ` array ` | ` [] ` | Array of custom languages to preload |
160+ | ` showLineNumbers ` | ` boolean ` | ` false ` | Display line numbers alongside code |
161+ | ` startingLineNumber ` | ` number ` | ` 1 ` | Starting line number when line numbers are enabled |
158162| ` transformers ` | ` array ` | ` [] ` | Custom Shiki transformers for modifying the highlighting output |
159163| ` cssVariablePrefix ` | ` string ` | ` '--shiki' ` | Prefix for CSS variables storing theme colors |
160164| ` defaultColor ` | ` string \| false ` | ` 'light' ` | Default theme mode when using multiple themes, can also disable default theme |
@@ -221,12 +225,12 @@ Custom themes can be passed as a TextMate theme in JavaScript object. For exampl
221225``` tsx
222226import tokyoNight from " ../styles/tokyo-night.json" ;
223227
224- // Using the component
228+ // Component
225229<ShikiHighlighter language = " tsx" theme = { tokyoNight } >
226230 { code .trim ()}
227231</ShikiHighlighter >
228232
229- // Using the hook
233+ // Hook
230234const highlightedCode = useShikiHighlighter (code , " tsx" , tokyoNight );
231235```
232236
@@ -237,12 +241,12 @@ Custom languages should be passed as a TextMate grammar in JavaScript object. Fo
237241``` tsx
238242import mcfunction from " ../langs/mcfunction.tmLanguage.json" ;
239243
240- // Using the component
244+ // Component
241245<ShikiHighlighter language = { mcfunction } theme = " github-dark" >
242246 { code .trim ()}
243247</ShikiHighlighter >
244248
245- // Using the hook
249+ // Hook
246250const highlightedCode = useShikiHighlighter (code , mcfunction , " github-dark" );
247251```
248252
@@ -254,7 +258,7 @@ For dynamic highlighting scenarios where language selection happens at runtime:
254258import mcfunction from " ../langs/mcfunction.tmLanguage.json" ;
255259import bosque from " ../langs/bosque.tmLanguage.json" ;
256260
257- // With the component
261+ // Component
258262<ShikiHighlighter
259263 language = " typescript"
260264 theme = " github-dark"
@@ -263,7 +267,7 @@ import bosque from "../langs/bosque.tmLanguage.json";
263267 { code .trim ()}
264268</ShikiHighlighter >
265269
266- // With the hook
270+ // Hook
267271const highlightedCode = useShikiHighlighter (code , " typescript" , " github-dark" , {
268272 customLanguages: [mcfunction , bosque ],
269273});
@@ -274,17 +278,82 @@ const highlightedCode = useShikiHighlighter(code, "typescript", "github-dark", {
274278``` tsx
275279import { customTransformer } from " ../utils/shikiTransformers" ;
276280
277- // Using the component
281+ // Component
278282<ShikiHighlighter language = " tsx" transformers = { [customTransformer ]} >
279283 { code .trim ()}
280284</ShikiHighlighter >
281285
282- // Using the hook
286+ // Hook
283287const highlightedCode = useShikiHighlighter (code , " tsx" , " github-dark" , {
284288 transformers: [customTransformer ],
285289});
286290```
287291
292+ ### Line Numbers
293+
294+ Display line numbers alongside your code, these are CSS-based
295+ and can be customized with CSS variables:
296+
297+ ``` tsx
298+ // Component
299+ <ShikiHighlighter
300+ language = " javascript"
301+ theme = " github-dark"
302+ showLineNumbers,
303+ startingLineNumber = { 0 } // default is 1
304+ >
305+ { code }
306+ </ShikiHighlighter >
307+
308+ <ShikiHighlighter
309+ language = " python"
310+ theme = " github-dark"
311+ showLineNumbers
312+ startingLineNumber = { 0 }
313+ >
314+ { code }
315+ </ShikiHighlighter >
316+
317+ // Hook (import 'react-shiki/css' for line numbers to work)
318+ const highlightedCode = useShikiHighlighter (code , " javascript" , " github-dark" , {
319+ showLineNumbers: true ,
320+ startingLineNumber: 0 ,
321+ });
322+ ```
323+
324+ > [ !NOTE]
325+ > When using the hook with line numbers, import the CSS file for the line numbers to work:
326+ > ``` tsx
327+ > import ' react-shiki/css' ;
328+ > ` ` `
329+ > Or provide your own CSS counter implementation and styles for ` .line - numbers ` (line ` span ` ) and ` .has - line - numbers ` (container ` code ` element)
330+
331+ Available CSS variables for customization:
332+ ` ` ` css
333+ -- line - numbers - foreground : rgba (107 , 114 , 128 , 0.5 );
334+ -- line - numbers - width : 2ch ;
335+ -- line - numbers - padding - left : 0ch ;
336+ -- line - numbers - padding - right : 2ch ;
337+ -- line - numbers - font - size : inherit ;
338+ -- line - numbers - font - weight : inherit ;
339+ -- line - numbers - opacity : 1 ;
340+ ```
341+
342+ You can customize them in your own CSS or by using the style prop on the component:
343+ ``` tsx
344+ <ShikiHighlighter
345+ language = " javascript"
346+ theme = " github-dark"
347+ showLineNumbers
348+ style = { {
349+ ' --line-numbers-foreground' : ' #60a5fa' ,
350+ ' --line-numbers-width' : ' 3ch'
351+ }}
352+ >
353+ { code }
354+ </ShikiHighlighter >
355+ ```
356+
288357## Integration
289358
290359### Integration with react-markdown
0 commit comments