@sveltek/rehype-shiki
v0.31.0
Published
A custom Rehype plugin for Shiki.
Downloads
22
Readme
[!NOTE]
While the API is solid and mostly complete, some changes may still occur before the first stable release.
Ideas, suggestions and code contributions are welcome.
If you find any issues or bugs, please report them so the project can be improved.
Core Concepts
- Provides super easy customization
- Includes preconfigured setup under the hood
- Dynamically loads languages on demand
- Caches highlighter instance and other details
- Allows advanced control over highlighter data
- Uses officially recommended fine-grained modules
- Follows best performance practices and guides
Installation
[!NOTE]
Package
@shikijs/themesis optional if you plan to use custom theme.
# via pnpm
pnpm add -D @sveltek/rehype-shiki @shikijs/langs @shikijs/themes# via npm
npm install -D @sveltek/rehype-shiki @shikijs/langs @shikijs/themesUsage
Global
import { svelteMarkdown } from '@sveltek/markdown'
import { rehypeShiki } from '@sveltek/rehype-shiki'
svelteMarkdown({
plugins: {
rehype: [[rehypeShiki, options]],
},
})Layouts
import { svelteMarkdown } from '@sveltek/markdown'
import { rehypeShiki } from '@sveltek/rehype-shiki'
svelteMarkdown({
layouts: [
{
name: 'layout-name',
path: 'path/to/custom/file.svelte',
plugins: {
rehype: [[rehypeShiki, options]],
},
},
],
})Entries
import { svelteMarkdown } from '@sveltek/markdown'
import { rehypeShiki } from '@sveltek/rehype-shiki'
svelteMarkdown({
entries: [
{
name: 'entry-name',
path: 'path/to/custom/file.svelte',
plugins: {
rehype: [[rehypeShiki, options]],
},
},
],
})Example
Minimal Shiki config requires langs and themes registration.
Rehype Shiki doesn't include any defaults so you can start from scratch. These are the official recommendations from the Shiki docs to avoid all pre-built bundles and only import what you really need.
import { svelteMarkdown } from '@sveltek/markdown'
import { rehypeShiki, type RehypeShikiOptions } from '@sveltek/rehype-shiki'
const rehypeShikiOptions: RehypeShikiOptions = {
langs: [
{ id: 'html', lang: import('@shikijs/langs/html') },
{ id: 'css', lang: import('@shikijs/langs/css') },
{ id: 'js', lang: import('@shikijs/langs/javascript') },
{ id: 'ts', lang: import('@shikijs/langs/typescript') },
{ id: 'svelte', lang: import('@shikijs/langs/typescript') },
// ...
],
themes: [
{
id: 'light',
name: 'github-light',
theme: import('@shikijs/themes/github-light'),
},
{
id: 'dark',
name: 'github-dark',
theme: import('@shikijs/themes/github-dark'),
},
// ...
],
}
svelteMarkdown({
plugins: {
rehype: [[rehypeShiki, rehypeShikiOptions]],
},
})Options
langs
- Type:
LanguageRegistration[] - Required:
true
Specifies an array of language registration.
Also, language aliases are not enabled by default, meaning if the language id is js, aliases like javascript, mjs, jsx etc. will not work unless you explicitly specify them.
{
langs: [
{ id: 'js', lang: import('@shikijs/langs/javascript') },
{
id: 'ts', // Specifies the lang ID (e.g. `js`, `ts`, `svelte`)
lang: import('@shikijs/langs/typescript'), // Specifies the language input
alias: ['typescript', 'mts', 'cts', 'tsx'], // Specifies a list of custom language aliases
},
// ...
]
}Custom Langs
{
langs: [
{ id: 'custom-lang-id', lang: customLang },
// ...
]
}themes
- Type:
ThemeRegistration[] - Required:
true
Specifies an array of theme registration.
{
themes: [
{
id: 'light',
name: 'github-light',
theme: import('@shikijs/themes/github-light'),
},
{
id: 'dark', // Specifies the theme ID (e.g. `light`, `dark`, `dim`)
name: 'github-dark', // Specifies the theme name (e.g. `github-dark`, `github-light`)
theme: import('@shikijs/themes/github-dark'), // Specifies the theme input
},
// ...
]
}Custom Themes
{
themes: [
{ id: 'custom-theme-id', name: 'custom-theme-name', theme: customTheme },
// ...
]
}codeToHtml
- Type:
(data: HighlighterData) => CodeToHastOptions - Default:
undefined
Specifies custom Shiki codeToHtml options.
{
codeToHtml: () => ({
defaultColor: 'dark',
tabIndex: false,
transformers: [
// Shiki transformers...
],
})
}It also allows advanced customization with highlighter data params:
{
codeToHtml: ({ code, lang, meta }) => {
// Feel free to use custom `parsing` util for extracting `metadata`
const metadata: Record<string, unknown> = parseMetadata(meta)
const lineNumbers = metadata?.lineNumbers
return {
transformers: [
{
name: 'transformer-metadata',
pre(node) {
node.properties['data-theme'] = `theme-name`
node.properties['data-lang'] = `${lang}`
node.properties['data-line-numbers'] = `${lineNumbers}`
},
// ...
},
// ...
],
}
}
}root
- Type:
(node: Hast.Element) => void - Default:
undefined
Specifies custom options for the root node (usually the <pre> tag).
{
root: (node) => {
node.tagName = 'div'
node.properties.id = 'code-highlight'
// ...
}
}License
Developed in 🇭🇷 Croatia, © Sveltek.
Released under the MIT license.
