Skip to content

Astro setup

This page is for Astro sites that do not use Starlight. For a Starlight site, follow Starlight setup.

The starlight-codeblocks/astro subpath exports an Astro integration. It adds Expressive Code to the site, with the features of the code blocks.

The source of the example site is in examples/astro on GitHub.

  1. Add the packages to the site.

    Terminal window
    npm install starlight-codeblocks astro-expressive-code
  2. Open astro.config.mjs.

  3. Add codeblocks() from starlight-codeblocks/astro to integrations. If the site uses mdx(), put codeblocks() before it.

    astro.config.mjs
    import mdx from '@astrojs/mdx';
    import { defineConfig } from 'astro/config';
    import codeblocks from 'starlight-codeblocks/astro';
    export default defineConfig({
    integrations: [
    mdx(),
    ],
    });
  4. If integrations has expressiveCode(), remove it. codeblocks() adds Expressive Code itself.

codeblocks() takes the same options as on a Starlight site. It also takes expressiveCode, with the options of astro-expressive-code.

Two features change Markdown outside the code blocks, so they are off until you turn them on:

  • Code tabs turn on directive syntax, such as :::name, in every Markdown page. Set codeTabs: {} to turn them on.
  • Inline code highlighting adds a stylesheet to every page. Set inlineHighlighting: {} to turn it on.
astro.config.mjs
codeblocks({
codeTabs: {},
inlineHighlighting: {},
}),

An ec.config.mjs file works as on a Starlight site. Its options replace the options in expressiveCode. If the file has a plugins list, add pluginCodeblocks() to it, as Starlight setup shows.

  • Side annotations and scrollycoding stay inside the content column. On a Starlight page with no table of contents, they use the free space on each side of the column.
  • Code blocks and inline code change theme with the Expressive Code theme selectors. By default, they follow prefers-color-scheme, and data-theme with the name of a theme on the html element.
  • With code tabs on, the integration turns on directive syntax in Sätteri. It turns any other directive back into its text, so text such as 16:9 stays as it is.
  • API cards show on links in code blocks only. Starlight sites also get them on links outside code blocks, such as those from starlight-pydocs.
  • With markdown: { processor: unified() }, code tabs need remark-directive in the remarkPlugins of unified().
  • The Copied label of colour swatches in prose uses the system colours of the browser.

A site that keeps its own expressiveCode() integration can add the plugins in ec.config.mjs. Give the options to pluginCodeblocks():

ec.config.mjs
import { pluginCodeblocks } from 'starlight-codeblocks/expressive-code';
export default {
tabWidth: 0,
plugins: [pluginCodeblocks({ focus: { style: 'dim' } })],
};

The features inside code blocks then work, but these parts are not there:

  • Code tabs and inline code highlighting, which need the Markdown plugin.
  • The built-in runtimes of the Run code button. Map each language to the URL of a runtime module, as in Without codeblocks().

tabWidth: 0 keeps tabs in the code. Without it, Expressive Code turns each tab into spaces.