rehype-pretty-code
is a Rehype plugin powered by the
shikiji
syntax highlighter that provides beautiful code blocks for Markdown or MDX. It works on both the server at build-time (avoiding runtime syntax highlighting) and on the client for dynamic highlighting.
Editor-Grade Highlighting
Enjoy the accuracy and granularity of VS Code's syntax highlighting engine and the popularity of its themes ecosystem — use any VS Code theme you want!
Line Numbers and Line Highlighting
Draw attention to a particular line of code.
Word Highlighting
Draw attention to a particular word or series of characters.
Inline Code Highlighting
The result of [1, 2, 3].join('-')
is '1-2-3'
.
Context Aware Inline Code
For instance, if you had the following code block:
When we refer to getStringLength
as a plain variable,
we can color it as a function. Same with function
, or
str
vs. str
, etc. This allows
you to semantically tie inline code with the nearest code block it's referring
to.
ANSI Highlighting
Inline ANSI: > Local: http://localhost:3000/
Table of Contents
- Installation
- Usage
- Styles
- Options
- Meta Strings
- Line Numbers
- Multiple Themes (Dark and Light Mode)
- Visitor Hooks
- Custom Highlighter
- React Server Component
Installation
Install via your terminal:
This package is ESM-only and currently supports shikiji
^0.7.0 - ^0.9.0
.
To use the latest version in Next.js, ensure your config file is
ESM
:next.config.mjs
. Here's a full example: rehype-pretty-code/website/next.config.mjs
Usage
The following works both on the server and on the client.
Note that unified
v11 is used as a dependency internally.
Ensure your unified
version is compatible.
MDX
The following example shows how to use this package with Next.js.
Disable the mdxRs
option if Rehype plugins do not work.
Styles
This library is unstyled. This means it does not provide a CSS file that applies styling by default. Rather, it provides logical attributes that you use to apply the styling yourself.
For instance, the following CSS prevents overflow and adds padding:
Features including highlighted lines, chars, and line numbers expose data attributes that enable you to add your own styling, which are explained below.
Options
grid
A grid style is present by default which allows line highlighting to span the entire width of a horizontally-scrollable code block.
You can disable this setting if necessary:
theme
The default theme is github-dark-dimmed
. Shikiji has a bunch of
pre-packaged themes,
which can be specified as a plain string:
You can use your own theme as well by passing the theme JSON:
keepBackground
To apply a custom background instead of inheriting the background from the theme:
defaultLang
When no code language is specified, inline code or code blocks will not be themed (nor will the background), which may appear incongruous with others.
In this case, you can specify a default language:
Or you can also specify default languages for inline code and code blocks separately:
transformers
Transformers are a
Shikiji-native way to manipulate the hAST
tree of the code blocks and further
extend the behavior of this plugin. The
shikiji-transformers
package provides some useful transformers.
Meta Strings
Code blocks are configured via the meta string on the top codeblock fence.
If your library also parses code blocks' meta strings, it may cause conflicts with
rehype-pretty-code
. This option allows you to filter out some part of the meta string before the library starts parsing it.
Highlight Lines
Place a numeric range inside {}
.
Styling: The line <span>
receives a data-highlighted-line
attribute that enables you to style via CSS.
Group Highlighted Lines By Id
Place an id after #
after the {}
. This allows you to color or style lines
differently based on their id.
Styling: The line <span>
receives a
data-highlighted-line-id="<id>"
attribute that enables you to style via CSS.
Highlight Chars
You can use either /
:
Or "
as a delimiter:
Different segments of chars can also be highlighted:
Styling: The chars <span>
receives a data-highlighted-chars
attribute to style via CSS.
To highlight only the third to fifth instances of carrot
, a numeric range can
be placed after the last /
.
Highlight only the third to fifth instances of carrot
and any instances of
apple
.
Group Highlighted Chars By Id
Place an id after #
after the chars. This allows you to color chars
differently based on their id.
Styling: The chars <span>
receives a data-chars-id="<id>"
attribute to style via CSS.
Highlight Inline Code
Append {:lang}
(e.g. {:js}
) to the end of inline code to highlight it like
a regular code block.
Highlight Plain Text
Append {:.token}
to the end of the inline code to highlight it based on a
token specified in your VS Code theme. Tokens start with a .
to differentiate
them from a language.
You can create a map of tokens to shorten this usage throughout your docs:
Titles
Add a file title to your code block, with text inside double quotes (""
):
Captions
Add a caption underneath your code block, with text inside double quotes (""
):
Line Numbers
CSS counters can be used to add line numbers.
If you want to conditionally show them, use showLineNumbers
:
Styling: <code>
will have attributes data-line-numbers
and
data-line-numbers-max-digits="n"
.
If you want to start line numbers at a specific number, use
showLineNumbers{number}
:
Multiple Themes (Dark and Light Mode)
Pass your themes to theme
, where the keys represent
the color mode:
Now, use the following CSS to display the variable colors — if a space is found in the theme name, then CSS variable keys based on the object are available (more info):
The <code>
and <pre>
elements will have the data attribute
data-theme="...themes"
, listing each theme value space-separated:
Visitor Hooks
To customize the HTML output, you can use visitor callback hooks to manipulate the hAST elements directly:
Custom Highlighter
To completely configure the highlighter, use the
getHighlighter
option. This is helpful if you'd like
to configure other Shikiji options, such as langs
.
React Server Component
The usage works directly in React Server Components. Here's an example:
Then, import the RSC into a page or another component:
See this example in action at /rsc.