---
# WARNING: Do not edit this file directly, your changes will be overwritten!
# This file is auto-generated from a template inside "scripts/typedoc/templates".
title: Plugin Hooks
---

import PropertySignature from '@components/PropertySignature.astro'

## Available plugin hooks

The engine calls the following hook functions in the order listed here:

### preprocessLanguage

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext)\>
</PropertySignature>

Allows preprocessing the code block's [language](/reference/core-api/#language) identifier before loading language-specific defaults into
[props](/reference/core-api/#props).

The Text Markers plugin uses this hook to override the `diff` language identifier with the language specified in the `lang` meta option (if given) to allow using diff syntax to mark inserted and deleted lines while using another language for syntax highlighting.

### preprocessMetadata

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext)\>
</PropertySignature>

Allows preprocessing the meta string and the language before any plugins can modify the code.

Plugins are expected to use this hook to remove any of their syntax from the meta string. Removed information can either be stored internally or used to create annotations.

As the code still matches the plaintext in the containing Markdown/MDX document at this point, this hook can be used to apply annotations by line numbers.

### preprocessCode

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext)\>
</PropertySignature>

Allows preprocessing the code before any language-specific hooks are run.

Plugins are expected to use this hook to remove any of their syntax that could disturb annotation plugins like syntax highlighters. Removed information can either be stored internally or used to create annotations.

Plugins can also use this hook to insert new code, e.g. to add type information for syntax highlighters, or to provide functionality to include external files into the code block.

### performSyntaxAnalysis

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext)\>
</PropertySignature>

Allows analyzing the preprocessed code and collecting language-specific syntax annotations.

This hook is used by the syntax highlighting plugin to run the code through `Shiki` and to create annotations from the returned syntax tokens.

These annotations are then available to the following hooks and will be used during rendering.

### postprocessAnalyzedCode

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext)\>
</PropertySignature>

Allows postprocessing the code plaintext after collecting syntax annotations.

Plugins are expected to use this hook to remove any parts from the code that should not be contained in the output. For example, if a plugin added declarations or type information during the `preprocessCode` hook to provide information to the syntax highlighter, the declarations could now be removed again.

After this hook has finished processing, the plaintext of all code lines becomes read-only.

### annotateCode

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext)\>
</PropertySignature>

Allows annotating the final code plaintext.

As the code is read-only at this point, plugins can use this hook to create annotations on lines or inline ranges matching a specific search term.

### postprocessAnnotations

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext)\>
</PropertySignature>

Allows applying final changes to annotations before rendering.

After this hook has finished processing, all annotations become read-only and the engine starts rendering the code blocks line by line.

### postprocessRenderedLine

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`PostprocessRenderedLineContext`](/reference/plugin-hooks/#postprocessrenderedlinecontext)\>
</PropertySignature>

Allows editing the AST of a single line of code after all annotations were rendered.

### postprocessRenderedBlock

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`PostprocessRenderedBlockContext`](/reference/plugin-hooks/#postprocessrenderedblockcontext)\>
</PropertySignature>

Allows editing the AST of the entire code block after all annotations were rendered and all lines were postprocessed.

### postprocessRenderedBlockGroup

<PropertySignature>
- Type: [`ExpressiveCodeHook`](/reference/plugin-hooks/#expressivecodehook)\<[`PostprocessRenderedBlockGroupContext`](/reference/plugin-hooks/#postprocessrenderedblockgroupcontext)\>
</PropertySignature>

Allows editing the ASTs of all code blocks that were rendered as part of the same group, as well as the AST of the group root element that contains all group blocks.

Groups are defined by the calling code. For example, a rehype plugin using Expressive Code to render code blocks could provide authors with a way to group related code blocks together.

This hook is used by the frames plugin to display multiple code blocks as editor file tabs.

Note: Even if a code block is not part of any group, this hook will still be called. Standalone code blocks are treated like a group containing only a single block.

## Referenced types

### ExpressiveCodeHook

<PropertySignature>
- Type: (`context`) => `void` \| `Promise`\<`void`\>
</PropertySignature>

#### Type parameters

| Parameter | Value |
| :------ | :------ |
| `ContextType` | [`ExpressiveCodeHookContext`](/reference/plugin-hooks/#expressivecodehookcontext) |

The base type of all hooks. It is a function that gets called by the engine and receives a context object. The context type defaults to [ExpressiveCodeHookContext](/reference/plugin-hooks/#expressivecodehookcontext), but can vary by hook, so see the list of available hooks for the correct type.

#### Arguments

| Parameter | Type |
| :------ | :------ |
| `context` | `ContextType` |

### ExpressiveCodeHookContext

A context object that the engine passes to most hook functions.

It provides access to theme-dependent CSS variables, all resolved style variants based on the configured themes and settings, and the config-dependent wrapper class name.

#### Properties

##### addGutterElement

<PropertySignature>
- Type: (`element`) => `void`
</PropertySignature>

Registers a gutter element for the current code block.

The engine calls the `renderLine` function of the gutter elements registered by all plugins for every line of the code block. The returned elements are then added as children to the line's gutter container.

###### Arguments

| Parameter | Type |
| :------ | :------ |
| `element` | `GutterElement` |

##### addStyles

<PropertySignature>
- Type: (`css`) => `void`
</PropertySignature>

Adds CSS styles to the document that contains the rendered code.

All styles are scoped to Expressive Code by default, so they will not affect the rest of the page. SASS-like nesting is supported. If you want to add global styles, you can use the `@at-root` rule or target `:root`, `html` or `body` in your selectors.

The engine's `render` function returns all added styles in a string array along with the rendered group and block ASTs. The calling code must take care of actually adding these styles to the page. For example, it could insert them into a `<style>` element before the rendered code block.

**Note for integration authors:** If you are rendering multiple code block groups on the same HTML page, you should deduplicate the returned styles at the page level. Expressive Code deduplicates styles added to the same group before returning them, but is not aware which styles are already present on the page.

**Note for plugin authors:** If you are adding the same styles to every block, consider using the `baseStyles` property of the plugin instead. This allows integrations to optionally extract these styles into a separate CSS file.

###### Arguments

| Parameter | Type |
| :------ | :------ |
| `css` | `string` |

##### codeBlock

<PropertySignature>
- Type: [`ExpressiveCodeBlock`](/reference/core-api/#expressivecodeblock)
</PropertySignature>

##### config

<PropertySignature>
- Type: `ResolvedExpressiveCodeEngineConfig`
</PropertySignature>

The Expressive Code engine configuration, with all optional properties resolved to their default values.

##### cssVar

<PropertySignature>
- Type: (`styleSetting`, `fallbackValue`?) => `string`
</PropertySignature>

Returns a CSS variable reference for the given style setting. The CSS variable name is automatically generated based on the setting path.

You can optionally pass a fallback value that will be added to the CSS `var()` function call (e.g. `var(--ec-xyz, fallbackValue)`) in case the referenced variable is not defined or unsupported. However, this should rarely be the case as the engine automatically generates CSS variables for all style settings if the plugin's `styleSettings` property is set.

###### Arguments

| Parameter | Type |
| :------ | :------ |
| `styleSetting` | [`StyleSettingPath`](/reference/plugin-api/#stylesettingpath) |
| `fallbackValue`? | `string` |

###### Example

```ts
cssVar('frames.fontSize')
// ↓↓↓
'var(--ec-frames-fontSize)'

cssVar('frames.fontSize', '2rem')
// ↓↓↓
'var(--ec-frames-fontSize, 2rem)'
```

##### cssVarName

<PropertySignature>
- Type: (`styleSetting`) => `string`
</PropertySignature>

Returns the CSS variable name for the given style setting. The CSS variable name is automatically generated based on the setting path.

###### Arguments

| Parameter | Type |
| :------ | :------ |
| `styleSetting` | [`StyleSettingPath`](/reference/plugin-api/#stylesettingpath) |

###### Example

```ts
cssVarName('frames.fontSize')
// ↓↓↓
'--ec-frames-fontSize'
```

##### groupContents

<PropertySignature>
- Type: readonly \{ `codeBlock`: `ExpressiveCodeBlock` \}[]
</PropertySignature>

##### locale

<PropertySignature>
- Type: `string`
</PropertySignature>

##### styleVariants

<PropertySignature>
- Type: [`StyleVariant`](/reference/plugin-api/#stylevariant)[]
</PropertySignature>

### PostprocessRenderedLineContext

A context object that the engine passes to the `postprocessRenderedLine` hook function.

In addition to the properties made available by [ExpressiveCodeHookContext](/reference/plugin-hooks/#expressivecodehookcontext), it provides access to information about the line currently being rendered, and allows modifying the rendered output.

#### Additional properties

##### line

<PropertySignature>
- Type: [`ExpressiveCodeLine`](/reference/core-api/#expressivecodeline)
</PropertySignature>

A reference to the line that is currently being rendered. It is read-only at this point, but you can access all line properties, including its source code and annotations.

##### lineIndex

<PropertySignature>
- Type: `number`
</PropertySignature>

The 0-based index of the line inside the code block.

##### renderData

<PropertySignature>
- Type: `Object`
</PropertySignature>

Allows modifying the line's rendered output. The `lineAst` property of this object contains the [Hypertext Abstract Syntax Tree (HAST)](https://github.com/syntax-tree/hast) node representing the rendered line.

You have full control over the `lineAst` property to modify the rendered output. For example, you could add a class name to the line's root element, or you could wrap the entire line in a custom element.

There is a wide range of existing utility packages that you can use to manipulate HAST elements. For more information, see the [list of utilities](https://github.com/syntax-tree/hast#list-of-utilities) in the HAST documentation.

###### Object properties

<dl class="type-declaration-list">
<dt>lineAst</dt>
<dd>
<PropertySignature>
- Type: `Element`
</PropertySignature>
</dd>
</dl>

##### renderEmptyLine

<PropertySignature>
- Type: `RenderEmptyLineFn`
</PropertySignature>

Allows rendering an empty line that is not part of the original code.

Some plugins may need to render lines that are not part of the original code, e.g. to display the expected output of a call right inside the code block. To align such lines with the original code, plugins can request an empty line from the engine using this function.


### PostprocessRenderedBlockContext

A context object that the engine passes to the `postprocessRenderedBlock` hook function.

In addition to the properties made available by [ExpressiveCodeHookContext](/reference/plugin-hooks/#expressivecodehookcontext), it provides access to render data of the code block currently being rendered, and allows modifying the rendered output.

#### Additional properties

##### renderData

<PropertySignature>
- Type: `Object`
</PropertySignature>

Allows modifying the block's rendered output. The `blockAst` property of this object contains the [Hypertext Abstract Syntax Tree (HAST)](https://github.com/syntax-tree/hast) node representing the rendered block.

You have full control over the `blockAst` property to modify the rendered output. For example, you could add a class name to the block's root element, wrap the entire block in a custom element, or traverse its children to find specific elements and modify them.

There is a wide range of existing utility packages that you can use to manipulate HAST elements. For more information, see the [list of utilities](https://github.com/syntax-tree/hast#list-of-utilities) in the HAST documentation.

###### Object properties

<dl class="type-declaration-list">
<dt>blockAst</dt>
<dd>
<PropertySignature>
- Type: `Element`
</PropertySignature>
</dd>
</dl>

##### renderEmptyLine

<PropertySignature>
- Type: `RenderEmptyLineFn`
</PropertySignature>

Allows rendering an empty line that is not part of the original code.

Some plugins may need to render lines that are not part of the original code, e.g. to display the expected output of a call right inside the code block. To align such lines with the original code, plugins can request an empty line from the engine using this function.


### PostprocessRenderedBlockGroupContext

A context object that the engine passes to the `postprocessRenderedBlockGroup` hook function.

It provides access to information about the code block group currently being rendered, and allows modifying the rendered output.

#### Properties

##### addStyles

<PropertySignature>
- Type: (`css`) => `void`
</PropertySignature>

See [ExpressiveCodeHookContext.addStyles](/reference/plugin-hooks/#addstyles).

###### Arguments

| Parameter | Type |
| :------ | :------ |
| `css` | `string` |

##### pluginStyles

<PropertySignature>
- Type: \{ `pluginName`: `string`; `styles`: `string` \}[]
</PropertySignature>

A list of styles that plugins added to the current code block group using the `addStyles` hook context function. Each item contains the plugin name and the styles it added. You have full control over the styles at this point and can add, modify or remove them as needed.

##### renderData

<PropertySignature>
- Type: `Object`
</PropertySignature>

Allows modifying the rendered output of a group of code blocks. The `groupAst` property of this object contains the [Hypertext Abstract Syntax Tree (HAST)](https://github.com/syntax-tree/hast) parent node surrounding all rendered blocks.

This is the only property that allows you to modify the wrapper element of the entire group. You have full control over it to modify the rendered output. For example, you could add a class name to the group’s root element, or you could wrap the entire group in a custom element.

###### Object properties

<dl class="type-declaration-list">
<dt>groupAst</dt>
<dd>
<PropertySignature>
- Type: `Element`
</PropertySignature>
</dd>
</dl>

##### renderedGroupContents

<PropertySignature>
- Type: readonly \{ `codeBlock`: `ExpressiveCodeBlock`; `renderedBlockAst`: `Element` \}[]
</PropertySignature>

An array of objects, each containing a reference to the code block, and its rendered HAST output. This is the same HAST element per block that is also available in the `renderData` property of the `postprocessRenderedBlock` hook context.
