Using Transformers for Shiki to enrich Syntax Highlighting in Astro
LaunchFast Logo LaunchFast

Using Transformers for Shiki to enrich Syntax Highlighting in Astro

Rishi Raj Jain
Using GreenSock Animation Platform (GSAP) in Astro: A Step-by-Step Guide

In this guide, you will learn how to use transformers for Shiki syntax highlighter in an Astro application. You will go through the process of setting up a new Astro project, installing the transformers for Shiki, and representing code additions and deletions. You will also learn how to focus on specific lines in a visually appealing manner.

Prerequisites

You’ll need the following:

Table Of Contents

Create a new Astro application

Let’s get started by creating a new Astro project. Execute the following command:

Terminal window
npm create astro@latest my-app

npm create astro is the recommended way to scaffold an Astro project quickly.

When prompted, choose:

  • Empty when prompted on how to start the new project.
  • Yes when prompted if plan to write Typescript.
  • Strict when prompted how strict Typescript should be.
  • Yes when prompted to install dependencies.
  • Yes when prompted to initialize a git repository.

Once that’s done, you can move into the project directory and start the app:

Terminal window
cd my-app
npm run dev

The app should be running on localhost:4321.

Now, let’s move on to integrating transformers for Shiki in your Astro application.

Integrate Transformers for Shiki in your Astro project

Install Transformers for Shiki

Execute the command below to install the necessary package for using transformers for Shiki:

Terminal window
npm install @shikijs/transformers

The command installs the following library:

  • @shikijs/transformers: A collection of transformers for shiki.

That’s the only library required to represent code in a visually appealing manner. Let’s update our Astro configuration to load these transformers.

Load Transformers for Shiki in Astro Configuration

To see the transformers for Shiki in effect, import the following in your Astro configuration file (astro.config.mjs).

  • transformerNotationDiff: Allows you to represent a change in a line of code.
  • transformerMetaHighlight: Allows you to highlight a line of code.
  • transformerNotationFocus: Allows you to focus a line of code.
import { defineConfig } from 'astro/config'
import {
transformerNotationDiff,
transformerNotationFocus,
transformerMetaHighlight
} from '@shikijs/transformers'
export default defineConfig({
markdown: {
syntaxHighlight: 'shiki',
shikiConfig: {
theme: 'github-dark',
transformers: [
transformerNotationDiff(),
transformerNotationFocus(),
transformerMetaHighlight(),
],
},
},
})

To demonstrate usage of these transformers, you will create a markdown file in the src/content/blog directory. Let’s create a sample.md inside the directory (src/content/blog) with the following content:

---
slug: 'sample'
title: 'Sample Title'
description: 'Sample Description'
created_at: 2024-04-15T00:00:00.000+00:00
---
```tsx
console.log("Introduction.")
console.log("Subtraction.") // [!code focus] // [!code --]
console.log("Addition.") // [!code focus] // [!code ++]
console.log("In focus.") // [!code focus]
console.log("End.")
```

In the markdown you’d see the lines that need to be representing differently have comments-like string in them. Here are those three strings:

  • // [!code --]: Allows you to specify which line should be represented as a deletion.
  • // [!code ++]: Allows you to specify which line should be represented as an addition.
  • // [!code focus]: Allows you to specify which line should be in focus. This is done via blurring out the rest of the lines in the code.

These specific strings output a CSS class with the line, that we need to define ourselves. Let’s define the particular CSS required in the src/pages/index.astro file:

---
// File: src/pages/index.astro // [!code focus]
---
// [!code focus]
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
<style is:global>
.line {
display: inline;
padding-bottom: 0;
}
.diff {
display: inline-block;
width: 100vw;
margin: 0 -12px;
padding: 0 12px;
}
.diff.add {
background-color: #0505;
}
.diff.remove {
background-color: #8005;
}
.diff:before {
position: absolute;
left: 40px;
}
.has-focused .line {
filter: blur(0.095rem);
}
.has-focused .focused {
filter: blur(0);
}
</style>
</head>
<body>
<h1>Astro<h1/>
</body>
</html>

Basically, you’ve added a set of classes that choose how an added, removed or focused line would look like. Now, render the markdown by using the default Shiki syntax highlighting in Astro. To do so, make the following additions in the index route:

---
// File: src/pages/index.astro // [!code focus]
const blogData = await Astro.glob('../content/blog/sample.md') // [!code focus]
const markdown = await blogData[0].compiledContent()
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
<style is:global>
.line {
display: inline;
padding-bottom: 0;
}
.diff {
display: inline-block;
width: 100vw;
margin: 0 -12px;
padding: 0 12px;
}
.diff.add {
background-color: #0505;
}
.diff.remove {
background-color: #8005;
}
.diff:before {
position: absolute;
left: 40px;
}
.has-focused .line {
filter: blur(0.095rem);
}
.has-focused .focused {
filter: blur(0);
}
</style>
</head>
<body>
<h1>Astro<h1/>
<article set:html={markdown} />
</body>
</html>

and you are done! As you have seen in this blog itself, you’d be able to see a visually appealing representation of code addition and deletion.

Build and Test your Astro application locally

To test the application, prepare a build and run the preview server using the command below:

Terminal window
npm run build && npm run preview

Conclusion

In this guide, you learned how to use Transformers for Shiki in an Astro application to focus into specific lines of code and in a visually appealing manner highlight code additions and deletions.

If you have any questions or comments, feel free to reach out to me on Twitter.

Learn More Astro vs Next.js: Choosing the Right Framework in 2024
Astro vs Next.js: Choosing the Right Framework in 2024 October 30, 2024
6 Essential Features Every Web Starter Kit Should Include
6 Essential Features Every Web Starter Kit Should Include October 26, 2024
Launch Fast with Astro 4.16
Launch Fast with Astro 4.16 October 23, 2024