Expressive Code plugins
codeblocks() adds every feature to Starlight for you. Behind it, each feature is an Expressive Code plugin. The starlight-codeblocks/expressive-code subpath exports these plugins, and a preset that returns all of them. A site that uses Expressive Code without Starlight, or with its own plugins list in ec.config.mjs, uses them there.
The preset
Section titled “The preset”pluginCodeblocks(options) returns every plugin, in the correct order, with the options of codeblocks(). Use the preset unless you have a reason to add plugins one by one. To leave a feature out, set its option to false:
export default {};On a Starlight site with codeblocks(), call pluginCodeblocks() with no argument. It then reads the options that you gave to codeblocks().
On a site without codeblocks(), give the preset Astro’s base as the second argument, if the site has one. Links in code that start with / then get it in front:
plugins: [pluginCodeblocks({}, { base: '/docs' })],Plugins
Section titled “Plugins”Each plugin takes the settings of its option, as the options reference lists them. The table gives the plugins in the order that the preset adds them.
| Plugin | Option | Feature |
|---|---|---|
pluginCore() |
none | Shared style settings and styles |
pluginNotation(settings) |
notation |
Comment notation |
pluginFocus(settings) |
focus |
Focus |
pluginLineStates(settings) |
lineStates |
Line states |
pluginWordDiff(settings) |
wordDiff |
Word-level diff |
pluginWhitespace() |
whitespace |
Visible whitespace |
pluginBrackets(settings) |
brackets |
Colourised brackets |
pluginSwatches(settings) |
swatches |
Colour swatches |
pluginShellCopy(settings) |
shellCopy |
Smart shell copy |
pluginCodeLinks({ base }) |
codeLinks |
Code links |
pluginApiLinks({ adapters, base }) |
apiLinks |
API auto-linking |
pluginPlaceholders(settings) |
placeholders |
Fill-in placeholders |
pluginMentions() |
mentions |
Code mentions |
pluginPermalinks() |
permalinks |
Line permalinks |
pluginHiddenLines() |
hiddenLines |
Hidden lines |
pluginExpandable(settings) |
expandable |
Expandable blocks |
pluginPlayground(playgrounds) |
playgrounds |
Open in playground |
pluginRunnable(settings) |
runnable |
Run code |
pluginFileIcons(settings) |
fileIcons |
File icons |
pluginCodeTabs(fileIcons) |
codeTabs |
Code tabs |
pluginWalkthrough() |
walkthrough |
Code walkthrough |
pluginCallouts() |
callouts |
Inline callouts |
pluginAnnotations() |
annotations |
Annotations and side annotations |
pluginFootnotes(settings) |
footnotes |
Footnotes |
pluginCodeLinks() and pluginApiLinks() take the base of the Astro site, for links that start with /. With codeblocks(), they read it from Astro. pluginApiLinks() has no default adapters. Give it the adapters from starlight-codeblocks/adapters/python and starlight-codeblocks/adapters/nextflow, or your own.
Rules for single plugins
Section titled “Rules for single plugins”If you add plugins one by one, follow these rules:
- Add
pluginCore()first. Every other plugin uses its style settings. - Add
pluginNotation()second, if any plugin after it reads directives. - Add the other plugins in the order of the table.
The order matters. For example, pluginPlayground() sends the copied text, so it must come after pluginShellCopy() and pluginPlaceholders(), which change that text. pluginCallouts() must come after pluginHiddenLines(), which rebuilds the lines of the block.
Without Starlight
Section titled “Without Starlight”Some features need more than an Expressive Code plugin. Without codeblocks(), these parts are not there:
- The
:::code-tabsdirective and inline code highlighting need the Markdown plugin thatcodeblocks()adds. - The
<CodeWalkthrough>and<Scrollycoding>components need Starlight. runnable.runtimesvalues are URLs that the browser imports as they are, becausecodeblocks()is not there to bundle the runtime modules. There are no built-in runtimes. Map each language to the URL of its runtime module, such ashttps://cdn.jsdelivr.net/npm/starlight-codeblocks/dist/runtimes/pyodide.mjs. The JavaScript and TypeScript runtimes arejavascript.mjsandtypescript.mjsin the same folder.- Expressive Code turns each tab into spaces, because
codeblocks()is not there to settabWidth: 0. SettabWidth: 0inec.config.mjs, so that tabs reach the code blocks unchanged.
The client scripts of interactive features load inline on each page that needs them, so the features work without a change to the build.