Skip to main content Svelte Highlight v7.11.0

Svelte Highlight

Svelte component library for highlighting code using highlight.js.

Installation

npm i svelte-highlight

pnpm i svelte-highlight

bun add svelte-highlight

yarn add svelte-highlight

Usage

The default Highlight component requires two props:

  • code: text to highlight
  • language: language grammar used to highlight the text

Import languages from svelte-highlight/languages.

See the Languages page for a list of supported languages.

<script>
  import Highlight from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = "const add = (a: number, b: number) => a + b;";
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<Highlight language={typescript} {code} />

Import styles from svelte-highlight/styles.

There are two ways to add styles:

  • Injected styles: JavaScript styles injected using the svelte:head API
  • CSS StyleSheet: CSS file that may require an appropriate file loader

Refer to the Styles page for a list of supported styles.

CSS StyleSheets can also be externally linked from a Content Delivery Network (CDN) like unpkg.com .

<link
  rel="stylesheet"
  href="https://unpkg.com/svelte-highlight/styles/github.css"
/>

Scoping styles

Themes target global .hljs selectors, so the last one injected wins. That is fine when every block shares one theme.

Use HighlightStyle when blocks on the same page need different themes, like a style gallery or a light snippet next to a dark one.

<script>
  import { Highlight, HighlightStyle } from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";
  import a11yDark from "svelte-highlight/styles/a11y-dark";
  import github from "svelte-highlight/styles/github";

  const code = "const add = (a: number, b: number) => a + b;";
</script>

<HighlightStyle theme={a11yDark}>
  <Highlight language={typescript} {code} />
</HighlightStyle>

<HighlightStyle theme={github}>
  <Highlight language={typescript} {code} />
</HighlightStyle>

Both themes render on the same page, scoped to each block:

const add = (a: number, b: number) => a + b;
const add = (a: number, b: number) => a + b;

Svelte Syntax Highlighting

Use the HighlightSvelte component for Svelte syntax highlighting.

<script>
  import { HighlightSvelte } from "svelte-highlight";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = `<button on:click={() => { console.log(0); }}>Click me</button>`;
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<HighlightSvelte {code} />

Auto-highlighting

The HighlightAuto component invokes the highlightAuto API from highlight.js.

<script>
  import { HighlightAuto } from "svelte-highlight";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = ".body { padding: 0; margin: 0; }";
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<HighlightAuto {code} />

Optionally, you can restrict language detection to a specific subset using the languageNames prop. This can improve performance and accuracy.

<script>
  import { HighlightAuto } from "svelte-highlight";
  import atomOneDark from "svelte-highlight/styles/atom-one-dark";

  const code = "const x = 42;";
</script>

<svelte:head>
  {@html atomOneDark}
</svelte:head>

<HighlightAuto {code} languageNames={["javascript", "typescript"]} />

Line Numbers

Use the LineNumbers component to render the highlighted code with line numbers.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers {highlighted} />
15
</Highlight>

Set hideBorder to true to hide the border of the line numbers column.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers {highlighted} hideBorder />
15
</Highlight>

By default, overflowing horizontal content is contained by a scrollbar.

Set wrapLines to true to apply a white-space: pre-wrap rule to the pre element.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers {highlighted} wrapLines />
15
</Highlight>

Use --style-props to customize visual properties.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers
15
    {highlighted}
16
    --line-number-color="rgba(255, 255, 255, 0.3)"
17
    --border-color="rgba(255, 255, 255, 0.1)"
18
    --padding-left="2em"
19
    --padding-right="1em"
20
  />
21
</Highlight>

Use container-level variables like --border-radius, --width, and --max-width to style the outer container without :global overrides.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers
15
    {highlighted}
16
    --border-radius="8px"
17
    --max-width="24rem"
18
  />
19
</Highlight>

Use startingLineNumber to customize the starting line number. By default, line numbers start at 1.

42
<script>
43
  import Highlight, { LineNumbers } from "svelte-highlight";
44
  import typescript from "svelte-highlight/languages/typescript";
45
  import horizonDark from "svelte-highlight/styles/horizon-dark";
46

47
  const code = "const add = (a: number, b: number) => a + b";
48
</script>
49

50
<svelte:head>
51
  {@html horizonDark}
52
</svelte:head>
53

54
<Highlight language={typescript} {code} let:highlighted>
55
  <LineNumbers {highlighted} startingLineNumber={42} />
56
</Highlight>

Use highlightedLines to highlight specific lines. Indices start at zero.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers {highlighted} highlightedLines={[0, 2, 3, 14]} />
15
</Highlight>

Use --unhighlighted-opacity or --unhighlighted-filter to de-emphasize the remaining lines and focus attention on the highlighted ones.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers
15
    {highlighted}
16
    highlightedLines={[0, 2, 3, 14]}
17
    --unhighlighted-opacity="0.4"
18
  />
19
</Highlight>

Use --highlighted-background to customize the background color of highlighted lines.

1
<script>
2
  import Highlight, { LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<Highlight language={typescript} {code} let:highlighted>
14
  <LineNumbers
15
    {highlighted}
16
    highlightedLines={[16]}
17
    --highlighted-background="rgba(150, 203, 254, 0.2)"
18
  />
19
</Highlight>

When using a custom slot, forward langtag and languageName from Highlight to LineNumbers.

1
<script>
2
  import { HighlightSvelte, LineNumbers } from "svelte-highlight";
3
  import horizonDark from "svelte-highlight/styles/horizon-dark";
4

5
  const code = "const add = (a: number, b: number) => a + b";
6
</script>
7

8
<svelte:head>
9
  {@html horizonDark}
10
</svelte:head>
11

12
<HighlightSvelte {code} langtag let:highlighted let:langtag let:languageName>
13
  <LineNumbers {highlighted} {langtag} {languageName} />
14
</HighlightSvelte>

Copy Button

Compose the CopyButton component alongside Highlight to add a copy-to-clipboard button. Position it by wrapping both in a relatively-positioned container.

By default, it copies the code using the native Clipboard API and shows a transient "copied" state.

<script>
  import Highlight, { CopyButton } from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = "const add = (a: number, b: number) => a + b";
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<div style="position: relative">
  <Highlight language={typescript} {code} />
  <CopyButton {code} />
</div>

Pass a copy function to override the default copy behavior—for example, to add logging or a custom toast.

<script>
  import Highlight, { CopyButton } from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = "const add = (a: number, b: number) => a + b";

  // Override the default Clipboard API behavior.
  function copy(code) {
    navigator.clipboard.writeText(code);
    console.log("Copied:", code);
  }
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<div style="position: relative">
  <Highlight language={typescript} {code} />
  <CopyButton {code} {copy} />
</div>

Provide custom button content using the default slot. The slot exposes a copied boolean.

<script>
  import Highlight, { CopyButton } from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = "const add = (a: number, b: number) => a + b";
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<div style="position: relative">
  <Highlight language={typescript} {code} />
  <CopyButton {code} let:copied --copy-right="2em">
    {#if copied}
      Copied!
    {:else}
      Copy
    {/if}
  </CopyButton>
</div>

Use --copy-* style props to customize the offset, size, and colors of the button.

<script>
  import Highlight, { CopyButton } from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = "const add = (a: number, b: number) => a + b";
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<div style="position: relative">
  <Highlight language={typescript} {code} />
  <CopyButton
    {code}
    --copy-background="rgba(255, 255, 255, 0.1)"
    --copy-color="#fff"
    --copy-border-radius="8px"
    --copy-size="2.5em"
  />
</div>

Compose CopyButton with LineNumbers by wrapping both in a relatively-positioned container.

1
<script>
2
  import Highlight, { CopyButton, LineNumbers } from "svelte-highlight";
3
  import typescript from "svelte-highlight/languages/typescript";
4
  import horizonDark from "svelte-highlight/styles/horizon-dark";
5

6
  const code = "const add = (a: number, b: number) => a + b";
7
</script>
8

9
<svelte:head>
10
  {@html horizonDark}
11
</svelte:head>
12

13
<div style="position: relative">
14
  <Highlight language={typescript} {code} let:highlighted>
15
    <LineNumbers {highlighted} />
16
  </Highlight>
17
  <CopyButton {code} />
18
</div>

When using a language tag alongside CopyButton, offset --langtag-top and --langtag-right so the tag sits to the left of the button.

<script>
  import Highlight, { CopyButton } from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";
  import horizonDark from "svelte-highlight/styles/horizon-dark";

  const code = "const add = (a: number, b: number) => a + b";
</script>

<svelte:head>
  {@html horizonDark}
</svelte:head>

<div style="position: relative">
  <Highlight
    language={typescript}
    {code}
    langtag
    --langtag-top="0"
    --langtag-right="3em"
    --langtag-padding="0.25em 0.5em"
    --langtag-font-size="0.75em"
  />
  <CopyButton {code} />
</div>

Language Targeting

All Highlight components apply a data-language attribute on the codeblock containing the language name.

This is also compatible with custom languages.

See the Languages page for a list of supported languages.

[data-language="css"] {
  /* custom style rules */
}

Language Tags

All Highlight components allow for a tag to be added at the top-right of the codeblock displaying the language name. Customize the language tag using style props. With LineNumbers, forward langtag and languageName from the parent slot (see Line Numbers above).

Defaults:

  • --langtag-top: 0
  • --langtag-right: 0
  • --langtag-background: inherit
  • --langtag-color: inherit
  • --langtag-border-radius: 0
  • --langtag-padding: 1em

See the Languages page for a list of supported languages.

<script>
  import { HighlightAuto } from "svelte-highlight";

  $: code = `body {
  padding: 0;
  color: red;
}`;
</script>

<HighlightAuto {code} langtag />

<HighlightAuto
  {code}
  langtag
  --langtag-top="0.5rem"
  --langtag-right="0.5rem"
  --langtag-background="linear-gradient(135deg, #2996cf, 80%, white)"
  --langtag-color="#fff"
  --langtag-border-radius="6px"
  --langtag-padding="0.5rem"
/>

Examples

Get started with example set-ups , including SvelteKit, Vite, Rollup, Routify, and Webpack.