Highlighting Code with Shiki: A Simple Guide for Modern Web Development
In modern web development, presenting code in a readable and aesthetically pleasing way is crucial for developers, especially when sharing or demonstrating snippets on your website or application. One of the most popular tools for this is Shiki, a syntax highlighter based on the TextMate grammars and VS Code themes. In this article, we'll walk you through how to integrate Shiki into a simple HTML page, customize your own theme, and highlight code dynamically with JavaScript modules.
Exciting? Don't have time? Just see below quick demo.
Setting Up Shiki for Syntax Highlighting
Shiki is designed to highlight code with a familiar look and feel of VS Code. It supports a wide range of programming languages, from JavaScript to TypeScript, Python, and more. The setup process is relatively simple and can be done directly in the browser using an ES module, making it highly compatible with modern web applications.
To begin, you’ll need to import Shiki into your HTML file. The easiest way is by using CDN links. In the example below, we use a link to esm.sh (or alternatively, esm.run) for a specific version of Shiki. You just need to ensure you specify the exact version of Shiki you intend to use, such as version 1.24.4:
<script type="module">
import { codeToHtml } from 'https://esm.sh/[email protected]';
</script>
This import makes the codeToHtml
function available, which is the primary function for converting your code into HTML with syntax highlighting.
Customizing Your Highlighting Theme
One of the key features of Shiki is its ability to support custom themes. You can create your own theme to match your website’s design and feel. Here, we define a custom theme called my-theme. This theme consists of several syntax rules that define the foreground colors for different elements like keywords, strings, and functions:
const myTheme = {
name: 'my-theme',
settings: [
{
scope: ['keyword', 'storage.type'],
settings: { foreground: '#FD8DA3' }
},
{
scope: ['string', 'entity.name.tag'],
settings: { foreground: '#77D5A3' }
},
{
scope: ['entity.name.function', 'entity.name'],
settings: { foreground: '#BD9CFE' }
},
{
scope: ['variable'],
settings: { foreground: '#92A9FF' }
},
]
}
This custom theme allows you to modify the colors of various code components. For example, keywords and types like keyword
and storage.type
will be displayed in #FD8DA3, while strings and tags will have a different color (#77D5A3). You can adjust the color values to fit your preferences.
Displaying Highlighted Code
Once you’ve defined your theme, it’s time to use codeToHtml
to highlight your code. Here’s an example where we highlight a simple React component written in TypeScript:
const foo = document.getElementById('foo');
foo.innerHTML = await codeToHtml(`import { useState } from "react"
export function LikeCounter() {
const [likes, setLikes] = useState(0);
return <>
<div>{likes}</div>
<button onClick={ () => setLikes(likes + 1) }>Like</button>
<button onClick={ () => setLikes(0) }>Reset</button>
</>`, {
lang: 'tsx',
theme: myTheme
});
Here, codeToHtml
takes two parameters:
- The code string you want to highlight.
- An options object that contains the language (e.g.,
tsx
for TypeScript and JSX combined) and your custom theme.
The code snippet will then be inserted into the HTML element with the id="foo"
, dynamically generating a highlighted version of the code right on the page.
Points to Consider
While Shiki is a great tool for syntax highlighting, there are a few things to keep in mind to ensure you get the best results:
- Performance: Since Shiki works in the browser, it may cause slight delays on pages with large code blocks. To mitigate this, you can consider using server-side rendering or caching.
- Custom Themes: Creating a custom theme can be time-consuming, especially if you want fine-grained control over every syntax element. However, the payoff is a highly personalized look for your code.
- Language Support: While Shiki supports a wide range of languages, there may be instances where it doesn’t support a specific language or feature. Always test with your code before deploying.
Enhancing the User Experience
You can further improve the user experience by adding features like:
- Line Numbers: Consider integrating line numbers into the highlighted code for better readability.
- Copy to Clipboard: Implement a "copy to clipboard" button next to the highlighted code to make it easier for users to copy and use your code.
- Dark Mode: Ensure that your theme works well in both light and dark modes by testing it on different backgrounds and adjusting contrast levels.
Full Code Sample
<body>
<div id="foo"></div>
<script type="module">
// be sure to specify the exact version
import { codeToHtml } from 'https://esm.sh/[email protected]'
// or
// import { codeToHtml } from 'https://esm.run/[email protected]'
const myTheme = {
name: 'my-theme',
settings: [
{
scope: ['keyword', 'storage.type'],
settings: {
foreground: '#FD8DA3'
}
},
{
scope: ['string', 'entity.name.tag'],
settings: {
foreground: '#77D5A3'
}
},
{
scope: ['entity.name.function', 'entity.name'],
settings: {
foreground: '#BD9CFE'
}
},
{
scope: ['variable'],
settings: {
foreground: '#92A9FF'
}
},
]
}
const foo = document.getElementById('foo')
foo.innerHTML = await codeToHtml(`import { useState } from "react"
export function LikeCounter() {
const [likes, setLikes] = useState(0)
return <>
<div>{likes}</div>
<button onClick={ () => setLikes(likes + 1) }>Like</button>
<button onClick={ () => setLikes(0) }>Reset</button>
</>
}`, {
lang: 'tsx',
theme: myTheme
})
</script>
</body>
and here is the result
Finally
Shiki provides an easy, elegant way to highlight code in modern web applications. With its flexibility, customizable themes, and ability to highlight a wide range of languages, it’s a valuable tool for developers who want to showcase their code with style. Whether you’re building a developer blog, a documentation site, or just want to make your code snippets look better, Shiki can make your project stand out.
By following the steps outlined above, you can quickly set up Shiki in your project and start using it for dynamic, customizable code highlighting. Just remember to keep performance and customizability in mind as you implement this tool to ensure the best experience for your users.
Comments ()