Syntax highlighting for Svelte using highlight.js.
Try it in StackBlitz.
The Changelog is available on GitHub.
# npm
npm i svelte-highlight
# pnpm
pnpm i svelte-highlight
# Bun
bun i svelte-highlight
# Yarn
yarn add svelte-highlight
The Highlight
component requires two props:
code
: text to highlightlanguage
: language grammar used to highlight the text
Import languages from svelte-highlight/languages
.
See SUPPORTED_LANGUAGES.md for a list of supported languages.
<script>
import Highlight from "svelte-highlight";
import typescript from "svelte-highlight/languages/typescript";
const code = "const add = (a: number, b: number) => a + b;";
</script>
<Highlight language={typescript} {code} />
Import styles from svelte-highlight/styles
. See SUPPORTED_STYLES.md for a list of supported styles.
There are two ways to apply highlight.js
styles.
- Injected styles through svelte:head
- CSS StyleSheets
This component exports highlight.js
themes in JavaScript. Import the theme from svelte-highlight/styles
and inject it using the svelte:head API.
<script>
import Highlight from "svelte-highlight";
import typescript from "svelte-highlight/languages/typescript";
import github from "svelte-highlight/styles/github";
const code = "const add = (a: number, b: number) => a + b;";
</script>
<svelte:head>
{@html github}
</svelte:head>
<Highlight language={typescript} {code} />
Depending on your set-up, importing a CSS StyleSheet in Svelte may require a CSS file loader. SvelteKit/Vite automatically supports this. For Webpack, refer to examples/webpack.
<script>
import { Highlight } from "svelte-highlight";
import typescript from "svelte-highlight/languages/typescript";
import "svelte-highlight/styles/github.css";
const code = "const add = (a: number, b: number) => a + b;";
</script>
<Highlight language={typescript} {code} />
CSS StyleSheets can also be externally linked from a Content Delivery Network (CDN) like unpkg.com.
Warning
Using a CDN is best suited for prototyping and not recommended for production use.
HTML
<head>
<link
rel="stylesheet"
href="https://unpkg.com/svelte-highlight/styles/github.css"
/>
</head>
svelte:head
<svelte:head>
<link
rel="stylesheet"
href="https://unpkg.com/svelte-highlight/styles/github.css"
/>
</svelte:head>
Use the HighlightSvelte
component for Svelte syntax highlighting.
<script>
import { HighlightSvelte } from "svelte-highlight";
import github from "svelte-highlight/styles/github";
const code = `<button on:click={() => { console.log(0); }}>Increment {count}</button>`;
</script>
<svelte:head>
{@html github}
</svelte:head>
<HighlightSvelte {code} />
The HighlightAuto
component uses the highlightAuto API and attempts to guess what grammar to use based on the provided code
.
Warning
Auto-highlighting will result in a larger bundle size. Specify a language if possible.
<script>
import { HighlightAuto } from "svelte-highlight";
import github from "svelte-highlight/styles/github";
const code = `body {\n padding: 0;\n color: red;\n}`;
</script>
<svelte:head>
{@html github}
</svelte:head>
<HighlightAuto {code} />
Use the LineNumbers
component to render the highlighted code with line numbers.
<script>
import Highlight, { LineNumbers } from "svelte-highlight";
import typescript from "svelte-highlight/languages/typescript";
import atomOneDark from "svelte-highlight/styles/atom-one-dark";
const code = "const add = (a: number, b: number) => a + b";
</script>
<svelte:head>
{@html atomOneDark}
</svelte:head>
<Highlight language={typescript} {code} let:highlighted>
<LineNumbers {highlighted} />
</Highlight>
Hidden Border
Set hideBorder
to true
to hide the border of the line numbers column.
<Highlight language={typescript} {code} let:highlighted>
<LineNumbers {highlighted} hideBorder />
</Highlight>
By default, overflowing horizontal content is contained by a scrollbar.
Set wrapLines
to true
to hide the border of the line numbers column.
<Highlight language={typescript} {code} let:highlighted>
<LineNumbers {highlighted} wrapLines />
</Highlight>
The line number starts at 1
. Customize this via the startingLineNumber
prop.
<Highlight language={typescript} {code} let:highlighted>
<LineNumbers {highlighted} startingLineNumber={42} />
</Highlight>
Specify the lines to highlight using the highlightedLines
prop. Indices start at zero.
Use --highlighted-background
to customize the background color of highlighted lines.
<Highlight language={typescript} {code} let:highlighted>
<LineNumbers
{highlighted}
highlightedLines={[0, 2, 3, 14]}
--highlighted-background="#000"
/>
</Highlight>
Use --style-props
to customize styles.
Style prop | Description | Default value |
---|---|---|
--line-number-color | Text color of the line numbers | currentColor |
--border-color | Border color of the column of line numbers | currentColor |
--padding-left | Left padding for td elements |
1em |
--padding-right | Right padding for td elements |
1em |
--highlighted-background | Background color of highlighted lines | rgba(254, 241, 96, 0.2) |
<Highlight language={typescript} {code} let:highlighted>
<LineNumbers
{highlighted}
--line-number-color="pink"
--border-color="rgba(255, 255, 255, 0.2)"
--padding-left={0}
--padding-right="3em"
--highlighted-background="#000"
/>
</Highlight>
All Highlight
components apply a data-language
attribute on the codeblock containing the language name.
See SUPPORTED_LANGUAGES.md for a list of supported languages.
[data-language="css"] {
/* custom style rules */
}
Set langtag
to true
to display the language name in the top right corner of the code block.
Customize the language tag background
, color
, and border-radius
using style props.
See the Languages page for a list of supported languages.
Style prop | Description | Default value |
---|---|---|
--langtag-top | Top position of the langtag | 0 |
--langtag-right | Right position of the langtag | 0 |
--langtag-background | Background color of the langtag | inherit |
--langtag-color | Text color of the langtag | inherit |
--langtag-border-radius | Border radius of the langtag | 0 |
--langtag-padding | Padding of the langtag | 1em |
<script>
import { HighlightAuto } from "svelte-highlight";
$: code = `.body { padding: 0; margin: 0; }`;
</script>
<HighlightAuto {code} langtag />
<HighlightAuto
{code}
langtag
--langtag-background="linear-gradient(135deg, #2996cf, 80%, white)"
--langtag-color="#fff"
--langtag-border-radius="6px"
--langtag-padding="0.5rem"
/>
For custom language highlighting, pass a name
and register
function to the language prop.
Refer to the highlight.js language definition guide for guidance.
<script>
import { Highlight } from "svelte-highlight";
import hljs from "highlight.js";
const language = {
name: "custom-language",
register: (hljs) => {
return {
/** custom language rules */
contains: [],
};
},
};
</script>
<Highlight {language} code="..." />
Additional plugin languages can be installed and used separately.
This example uses the cURL
language plugin.
<script>
import { Highlight } from "svelte-highlight";
import curl from "highlightjs-curl";
import github from "svelte-highlight/styles/github";
const language = {
name: "curl", // Language name displayed in the langtag
register: curl,
};
const code = `curl -X POST "https://api.example.com/data" \\
-H "Content-Type: application/json" \\
-d '{"key": "value"}'`;
</script>
<svelte:head>
{@html github}
</svelte:head>
<Highlight {language} {code} />
You can use the await import
syntax for code-splitting.
In the example below, the HighlightAuto
component and injected styles are dynamically loaded.
<script>
import { onMount } from "svelte";
let component;
let styles;
onMount(async () => {
component = (await import("svelte-highlight")).HighlightAuto;
styles = (await import("svelte-highlight/styles/github")).default;
});
</script>
<svelte:head>
{#if styles}
{@html styles}
{/if}
</svelte:head>
<svelte:component
this={component}
langtag
code={`body {\n padding: 0;\n color: red;\n}`}
/>
Name | Type | Default value |
---|---|---|
code | any |
N/A (required) |
language | { name: string ; register: hljs => object } |
N/A (required) |
langtag | boolean |
false |
$$restProps
are forwarded to the top-level pre
element.
- on:highlight: fired after
code
is highlighted
<Highlight
language={typescript}
{code}
on:highlight={(e) => {
/**
* The highlighted HTML as a string.
* @example "<span>...</span>"
*/
console.log(e.detail.highlighted);
}}
/>
Name | Type | Default value |
---|---|---|
highlighted | string |
N/A (required) |
hideBorder | boolean |
false |
wrapLines | boolean |
false |
startingLineNumber | number |
1 |
highlightedLines | number[] |
[] |
$$restProps
are forwarded to the top-level div
element.
Name | Type | Default value |
---|---|---|
code | any |
N/A (required) |
langtag | boolean |
false |
$$restProps
are forwarded to the top-level pre
element.
- on:highlight: fired after
code
is highlighted
<HighlightSvelte
{code}
on:highlight={(e) => {
/**
* The highlighted HTML as a string.
* @example "<span>...</span>"
*/
console.log(e.detail.highlighted);
}}
/>
Name | Type | Default value |
---|---|---|
code | any |
N/A (required) |
langtag | boolean |
false |
$$restProps
are forwarded to the top-level pre
element.
- on:highlight: fired after
code
is highlighted
<HighlightAuto
{code}
on:highlight={(e) => {
/**
* The highlighted HTML as a string.
* @example "<span>...</span>"
*/
console.log(e.detail.highlighted);
/**
* The inferred language name
* @example "css"
*/
console.log(e.detail.language);
}}
/>
By default, example set-ups use Svelte 5. The exception is examples/vite@svelte-4
, which uses Svelte 4.