Home
Softono

Svelte Highlight

Open source MIT TypeScript
331
Stars
14
Forks
17
Issues
1
Watchers
2 months
Last Commit

 About Svelte Highlight

Syntax Highlighting for Svelte using highlight.js

Platforms

Web Self-hosted

Languages

TypeScript

Need Help Installing Svelte Highlight?

We provide expert installation service for this software. Our team will install, configure, and secure Svelte Highlight on your server. plans start at just $30.

Svelte Highlight

View on GitHub

svelte-highlight

NPM npm

Syntax highlighting for Svelte using highlight.js.

Try it in the Svelte REPL or StackBlitz.

Documentation

The Changelog is available on GitHub.

Installation

# npm
npm i svelte-highlight

# pnpm
pnpm i svelte-highlight

# Bun
bun i svelte-highlight

# Yarn
yarn add svelte-highlight

Basic Usage

The Highlight component requires two props:

  • code: text to highlight
  • language: 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} />

Styling

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.

  1. Injected styles through svelte:head
  2. CSS StyleSheets

Injected Styles

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} />

CSS StyleSheet

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} />

Linking from a CDN

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>

Svelte Syntax Highlighting

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} />

Auto-highlighting

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} />

Limiting Language Detection

You can restrict language auto-detection to a subset using the languageNames prop. This can improve performance and accuracy.

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

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

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

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

Line Numbers

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>

Wrapped Lines

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>

Custom Starting Line Number

The line number starts at 1. Customize this via the startingLineNumber prop.

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

Highlighted Lines

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>

Custom Styles

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>

Language Tag

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

<Highlight
  language={typescript}
  {code}
  langtag
  let:highlighted
  let:langtag
  let:languageName
>
  <LineNumbers {highlighted} {langtag} {languageName} />
</Highlight>

With HighlightAuto:

<HighlightAuto {code} langtag let:highlighted let:langtag let:languageName>
  <LineNumbers {highlighted} {langtag} {languageName} />
</HighlightAuto>

Language Targeting

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 */
}

Language Tags

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"
/>

Custom Language

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="..." />

If you're using TypeScript, use the LanguageType interface to type the language.

import type { LanguageType } from "svelte-highlight";

const language: LanguageType<"custom-language"> = {
  name: "custom-language",
  register: (hljs) => {
    return {
      /** custom language rules */
      contains: [],
    };
  },
};

Custom Plugin

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} />

Code-splitting

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}`}
/>

Component API

Highlight

Props

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.

Dispatched Events

  • 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);
  }}
/>

LineNumbers

Props

Name Type Default value
highlighted string N/A (required)
hideBorder boolean false
wrapLines boolean false
startingLineNumber number 1
highlightedLines number[] []
langtag boolean false
languageName string "plaintext"

$$restProps are forwarded to the top-level div element.

HighlightSvelte

Props

Name Type Default value
code any N/A (required)
langtag boolean false

$$restProps are forwarded to the top-level pre element.

Dispatched Events

  • 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);
  }}
/>

HighlightAuto

Props

Name Type Default value
code any N/A (required)
languages LanguageName[] undefined
langtag boolean false

$$restProps are forwarded to the top-level pre element.

Note: LanguageName is a union type of all supported language names, providing autocomplete and type safety. You can import it from svelte-highlight:

import type { LanguageName } from "svelte-highlight";

Dispatched Events

  • 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);
  }}
/>

Supported Languages

Supported Styles

Examples

By default, example set-ups use Svelte 5. The exception is examples/vite@svelte-4, which uses Svelte 4.

Changelog

License

MIT