Skip to content

Syntax Highlighting

Astro comes with built-in support for Shiki and Prism. This provides syntax highlighting for:

Add community integrations such as Expressive Code for even more text marking and annotation options in your code blocks.

A Markdown code block is indicated by a block with three backticks ``` at the start and end. You can indicate the programming language being used after the opening backticks to indicate how to color and style your code to make it easier to read.

```js
// Javascript code with syntax highlighting.
var fun = function lang(l) {
dateformat.i18n = require('./lang/' + l);
return true;
};
```

Astro’s Markdown code blocks are styled by Shiki by default, preconfigured with the github-dark theme. The compiled output will be limited to inline styles without any extraneous CSS classes, stylesheets, or client-side JS.

You can add a Prism stylesheet and switch to Prism’s highlighting, or disable Astro’s syntax highlighting entirely, with the markdown.syntaxHighlighting configuration option.

See the full markdown.shikiConfig reference for the complete set of Markdown syntax highlighting options available when using Shiki.

You can configure any built-in Shiki theme for your Markdown code blocks in your Astro config:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
markdown: {
shikiConfig: {
theme: 'dracula',
},
},
});
See the full Shiki config reference for the complete set of Markdown code block options.

Setting light and dark mode themes

Section titled Setting light and dark mode themes

You can specify dual Shiki themes for light and dark mode in your Astro config:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
markdown: {
shikiConfig: {
themes: {
light: 'github-light',
dark: 'github-dark',
},
},
},
});

Then, add Shiki’s dark mode CSS variables via media query or classes to apply to all your Markdown code blocks by default. Replace the .shiki class in the examples from Shiki’s documentation with .astro-code:

src/styles/global.css
@media (prefers-color-scheme: dark) {
.shiki,
.shiki span {
.astro-code,
.astro-code span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
/* Optional, if you also want font styles */
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
}
See the full Shiki config reference for the complete set of Markdown code block options.

Instead of using one of Shiki’s predefined themes, you can import a custom Shiki theme from a local file.

astro.config.mjs
import { defineConfig } from 'astro/config';
import customTheme from './my-shiki-theme.json';
export default defineConfig({
markdown: {
shikiConfig: {
theme: customTheme,
},
},
});

You can follow Shiki’s own theme documentation for more customization options for themes, light vs dark mode toggles, or styling via CSS variables.

Astro code blocks are styled using the .astro-code class, so you will need to replace the .shiki class in the examples with .astro-code.

There are two Astro components available for .astro and .mdx files to render code blocks: <Code /> and <Prism />.

You can reference the Props of these components using the ComponentProps type utility.

This component is powered internally by Shiki. It supports all popular Shiki themes and languages as well as several other Shiki options such as custom themes, languages, transformers, and default colors.

These values are passed to the <Code /> component using the theme, lang, transformers, and defaultColor attributes respectively as props. The <Code /> component will not inherit your shikiConfig settings for Markdown code blocks.

---
import { Code } from 'astro:components';
---
<!-- Syntax highlight some JavaScript code. -->
<Code code={`const foo = 'bar';`} lang="js" />
<!-- Optional: Customize your theme. -->
<Code code={`const foo = 'bar';`} lang="js" theme="dark-plus" />
<!-- Optional: Enable word wrapping. -->
<Code code={`const foo = 'bar';`} lang="js" wrap />
<!-- Optional: Output inline code. -->
<p>
<Code code={`const foo = 'bar';`} lang="js" inline />
will be rendered inline.
</p>
<!-- Optional: defaultColor -->
<Code code={`const foo = 'bar';`} lang="js" defaultColor={false} />

Added in: astro@4.11.0

Shiki transformers can optionally be applied to code by passing them in through the transformers property as an array. Since Astro v4.14.0, you can also provide a string for Shiki’s meta attribute to pass options to transformers.

Note that transformers only applies classes and you must provide your own CSS rules to target the elements of your code block.

src/pages/index.astro
---
import { transformerNotationFocus, transformerMetaHighlight } from '@shikijs/transformers'
import { Code } from 'astro:components'
const code = `const foo = 'hello'
const bar = ' world'
console.log(foo + bar) // [!code focus]
`
---
<Code
code={code}
lang="js"
transformers={[transformerMetaHighlight()]}
meta="{1,3}"
/>
<style is:global>
pre.has-focused .line:not(.focused) {
filter: blur(1px);
}
</style>

This component provides language-specific syntax highlighting for code blocks by applying Prism’s CSS classes. Note that you must provide a Prism CSS stylesheet (or bring your own) to style the classes.

To use the Prism highlighter component, you must install the @astrojs/prism package:

Terminal window
npm install @astrojs/prism

Then, you can import and use the <Prism /> component like any other Astro component, passing a language and the code to render.

---
import { Prism } from '@astrojs/prism';
---
<Prism lang="js" code={`const foo = 'bar';`} />

In addition to the list of languages supported by Prism, you can also use lang="astro" to display Astro code blocks.

If you opt to use Prism (either by configuring markdown.syntaxHighlighting: 'prism' or with the <Prism /> component), Astro will apply Prism’s CSS classes instead of Shiki’s to your code. You will need to bring your own CSS stylesheet for syntax highlighting to appear.

  1. Choose a premade stylesheet from the available Prism Themes.

  2. Add this stylesheet to your project’s public/ directory.

  3. Load this into your page’s <head> in a layout component via a <link> tag. (See Prism basic usage.)

You can also visit the list of languages supported by Prism for options and usage.

Contribute

What’s on your mind?

Create GitHub Issue

Quickest way to alert our team of a problem.

Community