Editor & Terminal Frames
Expressive Code supports rendering frames around your code blocks. By default, the type of frame (editor window or terminal window) is selected automatically based on the language identifier in your code block’s opening fence.
Frames can have optional titles, which are either taken from the code block’s meta string, or from a file name comment in the first lines of the code.
Usage in markdown / MDX
Section titled “Usage in markdown / MDX”Code editor frames
Section titled “Code editor frames”To make code blocks look like an editor window similar to VS Code, you must provide a file name that can be displayed in the open file tab.
To do this, you can either set the title attribute in the opening code fence to a file name, or add a file name comment to the first lines of the code.
See the markdown code below for examples of both methods:
```js title="my-test-file.js"console.log('Title attribute example')```
```html<!-- src/content/index.html --><div>File name comment example</div>```The rendered result looks like this:
console.log('Title attribute example')<div>File name comment example</div>Terminal frames
Section titled “Terminal frames”When encountering code blocks with a language identifier that is typically used for terminal sessions or shell scripts (ansi, bash, bat, batch, cmd, console, powershell, ps, ps1, psd1, psm1, sh, shell, shellscript, shellsession, zsh), Expressive Code performs additional checks to detect the frame type to use:
- If the code block contains a shell script file name in the
titleattribute of the opening code fence or a file name comment, or if the code starts with a shebang (#!), it is considered to be a script file instead of a terminal session, and is rendered with a code editor frame if a file name was provided, or as a plain code block otherwise. - In all other cases, the code block is considered to be a terminal session and rendered with a terminal frame.
In contrast to code editor frames, terminal frames do not require a title. The title bar will always be rendered, and you can optionally add a title using the title attribute:
```bashecho "This terminal frame has no title"```
```powershell title="PowerShell terminal example"Write-Output "This one has a title!"```The rendered result looks like this:
echo "This frame has no title"Write-Output "This one has a title!"File name comments
Section titled “File name comments”If a code block does not have a title attribute, Expressive Code supports automatically extracting a title from a file name comment inside your code.
The following conditions must be met for a comment to be recognized as a file name comment:
- It must appear within the first 4 lines of the code block.
- Its line must start with
//,<!--,/*or#, but not#!. Although not required, we recommend using the comment syntax matching your code block’s language. - It can optionally have a prefix that ends with a colon (
:). This allows you to prefix the file name with some text:// File name: index.js - The file name appears to be valid in the context of the code block’s language. For example, a comment containing a CSS file name in a JavaScript code block will be ignored.
Once a file name comment is found, it is removed from the code block’s content, and the extracted file name is used as the code block’s title.
Overriding frame types
Section titled “Overriding frame types”If you want to override the automatic frame type detection for some code blocks, you can add the frame="..." attribute to the opening code fence.
The supported values for this attribute are code, terminal, none and auto. The default value is auto.
```sh frame="none"echo "Look ma, no frame!"```
```ps frame="code" title="PowerShell Profile.ps1"# Without overriding, this would be a terminal framefunction Watch-Tail { Get-Content -Tail 20 -Wait $args }New-Alias tail Watch-Tail```The rendered result looks like this:
echo "Look ma, no frame!"# Without overriding, this would be a terminal framefunction Watch-Tail { Get-Content -Tail 20 -Wait $args }New-Alias tail Watch-TailUsage in the <Code> component
Section titled “Usage in the <Code> component”The frames plugin adds multiple props to the <Code> component that allow direct access to its features. The following props are available:
"terminal" | "code" | "none" | "auto" Default:
auto Allows you to override the automatic frame type detection for a code block.
The supported values are code, terminal, none and auto.
string The code block’s title. For terminal frames, this is displayed as the terminal window title, and for code frames, it’s displayed as the file name in an open file tab.
If no title is given, the plugin will try to automatically extract a title from a file name comment inside your code, unless disabled by the extractFileNameFromCode option.
Configuration
Section titled “Configuration”When using this plugin through a framework integration, you can configure it by passing options to the integration.
In addition, you can also override its default styles by adding a frames object to the styleOverrides engine config option. You can find a list of all overridable styles below.
Here are configuration examples for some popular site generators:
import { defineConfig } from 'astro/config'import astroExpressiveCode from 'astro-expressive-code'
export default defineConfig({ integrations: [ astroExpressiveCode({ // You can optionally override the plugin's default settings here frames: { // Example: Hide the "Copy to clipboard" button showCopyToClipboardButton: false, }, styleOverrides: { // You can optionally override the plugin's default styles here frames: { shadowColor: '#124', }, }, }), ],})import { defineConfig } from 'astro/config'import starlight from '@astrojs/starlight'
export default defineConfig({ integrations: [ starlight({ title: 'My Starlight site', expressiveCode: { // You can optionally override the plugin's default settings here frames: { // Example: Hide the "Copy to clipboard" button showCopyToClipboardButton: false, }, styleOverrides: { // You can optionally override the plugin's default styles here frames: { shadowColor: '#124', }, }, }, }), ],})import createMDX from '@next/mdx'import rehypeExpressiveCode from 'rehype-expressive-code'
/** @type {import('rehype-expressive-code').RehypeExpressiveCodeOptions} */const rehypeExpressiveCodeOptions = { // You can optionally override the plugin's default settings here frames: { // Example: Hide the "Copy to clipboard" button showCopyToClipboardButton: false, }, styleOverrides: { // You can optionally override the plugin's default styles here frames: { shadowColor: '#124', }, },}
/** @type {import('next').NextConfig} */const nextConfig = { reactStrictMode: true, pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"],}
const withMDX = createMDX({ extension: /\.mdx?$/, options: { remarkPlugins: [], rehypePlugins: [ // The nested array structure is required to pass options // to a rehype plugin [rehypeExpressiveCode, rehypeExpressiveCodeOptions], ], },})
export default withMDX(nextConfig)Available plugin options
Section titled “Available plugin options”You can configure the plugin’s features using the following options:
extractFileNameFromCode
Section titled “extractFileNameFromCode”boolean Default:
true If true, and no title was found in the code block’s meta string, the plugin will try to find and extract a comment line containing the code block file name from the first 4 lines of the code.
removeCommentsWhenCopyingTerminalFrames
Section titled “removeCommentsWhenCopyingTerminalFrames”boolean Default:
true If true, the “Copy to clipboard” button of terminal window frames will remove comment lines starting with # from the copied text.
This is useful to reduce the copied text to the actual commands users need to run, instead of also copying explanatory comments or instructions.
showCopyToClipboardButton
Section titled “showCopyToClipboardButton”boolean Default:
true If true, a “Copy to clipboard” button will be shown for each code block.
Available style overrides
Section titled “Available style overrides”This plugin adds a frames object to the styleOverrides engine config option, allowing you to customize the visual appearance of the rendered frames. The object contains the following properties:
copyIcon
Section titled “copyIcon”An inline SVG URL for the copy to clipboard icon.
Expects a string in the format url("data:image/svg+xml,..."), which can be generated from the contents of an SVG file using createInlineSvgUrl.
editorActiveTabBackground
Section titled “editorActiveTabBackground”The CSS background value for the active editor tab.
editorActiveTabBorderColor
Section titled “editorActiveTabBorderColor”The border color of the active editor tab.
editorActiveTabForeground
Section titled “editorActiveTabForeground”The foreground color of the active editor tab.
editorActiveTabIndicatorBottomColor
Section titled “editorActiveTabIndicatorBottomColor”The color of the indicator line displayed at the bottom border of the active editor tab.
editorActiveTabIndicatorHeight
Section titled “editorActiveTabIndicatorHeight”The height of the indicator lines highlighting the active editor tab. These are colorful lines that appear at the top and/or bottom of the active tab.
The individual line colors can be set in editorActiveTabIndicatorTopColor and editorActiveTabIndicatorBottomColor.
editorActiveTabIndicatorTopColor
Section titled “editorActiveTabIndicatorTopColor”The color of the indicator line displayed at the top border of the active editor tab.
editorBackground
Section titled “editorBackground”The background color of the code editor. This color is used for the “code” frame type.
editorTabBarBackground
Section titled “editorTabBarBackground”The CSS background value of the editor tab bar.
editorTabBarBorderBottomColor
Section titled “editorTabBarBorderBottomColor”({ theme }) => theme.colors['editorGroupHeader.tabsBorder'] || 'transparent' The color of the bottom border of the editor tab bar. This is an additional border that can be used to display a line between the editor tab bar and the code contents.
editorTabBarBorderColor
Section titled “editorTabBarBorderColor”The border color of the editor tab bar.
editorTabBorderRadius
Section titled “editorTabBorderRadius”The border radius to apply to the outer corners of editor tabs.
editorTabsMarginBlockStart
Section titled “editorTabsMarginBlockStart”The block margin (= top margin in horizontal writing mode) to apply inside the tab bar before the editor tabs.
editorTabsMarginInlineStart
Section titled “editorTabsMarginInlineStart”The inline margin (= left margin in horizontal writing mode) to apply inside the tab bar before the first editor tab.
frameBoxShadowCssValue
Section titled “frameBoxShadowCssValue”({ resolveSetting }) => `0.1rem 0.1rem 0.2rem ${resolveSetting('frames.shadowColor')}` The CSS value for the box shadow of the frame.
inlineButtonBackground
Section titled “inlineButtonBackground”({ resolveSetting }) => resolveSetting('frames.inlineButtonForeground') The background color of the copy button. This color is modified by the state-dependent opacity values specified in inlineButtonBackgroundIdleOpacity, inlineButtonBackgroundHoverOrFocusOpacity and inlineButtonBackgroundActiveOpacity.
inlineButtonBackgroundActiveOpacity
Section titled “inlineButtonBackgroundActiveOpacity”The opacity of the copy button background when pressed.
inlineButtonBackgroundHoverOrFocusOpacity
Section titled “inlineButtonBackgroundHoverOrFocusOpacity”The opacity of the copy button background when hovered or focused.
inlineButtonBackgroundIdleOpacity
Section titled “inlineButtonBackgroundIdleOpacity”The opacity of the copy button background when idle.
inlineButtonBorder
Section titled “inlineButtonBorder”({ resolveSetting }) => resolveSetting('frames.inlineButtonForeground') The border color of the copy button.
inlineButtonBorderOpacity
Section titled “inlineButtonBorderOpacity”The opacity of the copy button border.
inlineButtonForeground
Section titled “inlineButtonForeground”The foreground color of the copy button.
shadowColor
Section titled “shadowColor”({ theme, resolveSetting }) => theme.colors['widget.shadow'] || multiplyAlpha(resolveSetting('borderColor'), 0.75) The color to use for the shadow of the frame.
terminalBackground
Section titled “terminalBackground”The background color of the terminal window. This color is used for the “terminal” frame type.
terminalIcon
Section titled “terminalIcon”An inline SVG URL for the terminal icon.
Expects a string in the format url("data:image/svg+xml,..."), which can be generated from the contents of an SVG file using createInlineSvgUrl.
Defaults to three dots in a row.
terminalTitlebarBackground
Section titled “terminalTitlebarBackground”({ theme }) => theme.colors['titleBar.activeBackground'] || theme.colors['editorGroupHeader.tabsBackground'] The background color of the terminal title bar.
terminalTitlebarBorderBottomColor
Section titled “terminalTitlebarBorderBottomColor” theme.colors['titleBar.border'] || onBackground(resolveSetting('borderColor'), theme.type === 'dark' ? '#000000bf' : '#ffffffbf') The color of the border between the terminal title bar and the terminal contents.
terminalTitlebarDotsForeground
Section titled “terminalTitlebarDotsForeground”({ resolveSetting }) => resolveSetting('frames.terminalTitlebarForeground') The color of the three dots in the terminal title bar.
terminalTitlebarDotsOpacity
Section titled “terminalTitlebarDotsOpacity”The opacity of the three dots in the terminal title bar.
terminalTitlebarForeground
Section titled “terminalTitlebarForeground”The foreground color of the terminal title bar.
tooltipSuccessBackground
Section titled “tooltipSuccessBackground”({ theme }) => setLuminance(theme.colors['terminal.ansiGreen'] || '#0dbc79', 0.18) The background color of the tooltip shown after successfully copying the code.
tooltipSuccessForeground
Section titled “tooltipSuccessForeground”The foreground color of the tooltip shown after successfully copying the code.