Code Highlighting in Svelte with PrismJS

Syntax highlighting is really nice to have. But can be somewhat confusing to implement. Luckily, PrismJS was made so don't have to do it yourself. But it doesn't work automatically. Let's take a look at the code used by this site.

To get started, install PrismJS in your SvelteKit project folder.

html
npm i prismjs

And then install prism-svelte

javascript
npm i prism-svelte

Next, we don't want to write the same code every time, so you'll create a new 'Prism.svelte' component in your lib folder.


The code below will act as a template to process the code using Prism.

html
// Import the PrismJS stylesheet from the internet <svelte:head> <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.22.0/themes/prism-dark.min.css" rel="stylesheet" /> </svelte:head> <script> // Import the Prism library. import Prism from 'prismjs'; //This imports the prism-svelte library from github import 'prism-svelte'; //Create an empty string with backticks and add "export" to make it available to other components. export let code = ``; //Define a variable to set the language. export let lang; </script>

Then we can build our component's html structure. You can make it look fancy by wrapping the whole block in a div with class 'code' to add formatting. A 'language' class can let us treat the language as a separate element.

html
<div class="code"> <code> <div class="language">{lang}</div> </code> <br> <code> {@html Prism.highlight(code, Prism.languages[lang])} </code> </div>

Optionally, you can set the style to make it contained inside a black box with a border.

css
.language { font-family: monospace; width: 100%; } .code-block { display:block; background: var(--black); border: 1px solid var(--gray); border-radius: .3em; margin-bottom: 1em; max-width: 90dvw; word-break:break-all; white-space:break-spaces; } code { display:block; box-sizing: border-box; padding: 1em; padding-top: 0em; } .language { background: var(--gray2); padding: .25em; border-radius: .2em; }

Now your Prism.svelte component is ready! To add it to your svelte page or another component, import the prism component in the script tag. If you have the svelte extension for VS Code, you should be able to type "import Prism" and one of the auto-complete options should lead to the right path.

javascript
import Code from '../../../../lib/utilities/Prism.svelte';

And then define your code as a variable inside the svelte <Code /> template tag. Wrap your code in `backticks` to let javascript know that you don't want to execute the code.

javascript
<Code lang={"javascript"} code={`console.log("Hello, world!")`} />

The end result should appear like this on the page:

javascript
console.log("Hello, world!")

Errors

Some characters will break your formatting because Svelte thinks you're trying to close the code block or insert code into the page. For example, if you try to add <script> tags into your prism code block, Svelte gets confused and thinks you're trying to add two script tags into one component, which it doesn't allow.

VS Code red underlines

If this happens, all you need to do is add a backslash \ before the character. This is called character escaping. In this case, we escape the lash of the closing script tag.

escaping characters

You'll likely only need to do this for `backticks` and the script tag.

Themes

You may want to pick a different color scheme. PrismJS provides a nice number of themes out of the box. You just have to switch the theme in the import url to the name of the theme you want.

https://cdnjs.cloudflare.com/ajax/libs/prism/1.22.0/themes/prism-theme-name.min.css

A list of themes can be found on the PrismJS website.