# Code block

> Learn how to enhance your documentation with customizable code blocks featuring syntax highlighting, line highlighting, focusing, and more.

The `<CodeBlock>` component displays code examples with syntax highlighting. Code blocks support line highlighting, focusing, titles, and deep linking to make your code examples more readable and interactive.

## Usage

Use three backticks with an optional language identifier.

<div>
  ```js
  console.log("hello world")
  ```
</div>

````mdx Markdown
```js
console.log("hello world")
```
````

<Accordion title="Supported languages" defaultOpen>
  Fern supports [Shiki](https://shiki.matsu.io/) syntax highlighting for the following languages:

  * `javascript` (aliases: `js`, `node`)
  * `python`
  * `java`
  * `typescript` (aliases: `ts`)
  * `csharp`
  * `cpp`
  * `c`
  * `php`
  * `go`
  * `rust`
  * `ruby`
  * `swift`
  * `kotlin`
  * `sql`
  * `bash` (aliases: `shell`, `sh`)
  * `curl`
  * `markdown` (aliases: `md`)
  * `http`

  If you specify a language that's not on this list, Fern will still display the code block but without syntax highlighting.
</Accordion>

## Variants

### Titles

Add a title to your code snippet by adding a title after the language identifier. Alternatively, use a `title` prop (`title="Snippet with title"`) or `filename` prop (`filename="Snippet with title"`) to achieve the same result.

<div>
  ```js Snippet with title
  console.log("hello world")
  ```
</div>

````mdx Markdown
```js Snippet with title
console.log("hello world")
```
````

### Line highlighting

Highlight specific lines in your code snippet by placing a numeric range inside `{}`
after the language identifier. The range is inclusive and can be a single number, a comma-separated list of numbers, or ranges.

<div>
  ```js {2-4, 6} 
  console.log("Line 1");
  console.log("Line 2");
  console.log("Line 3");
  console.log("Line 4");
  console.log("Line 5");
  console.log("Line 6");
  ```
</div>

````markdown Markdown
```javascript {2-4, 6}
console.log("Line 1");
console.log("Line 2");
console.log("Line 3");
console.log("Line 4");
console.log("Line 5");
console.log("Line 6");
```
````

### Line focusing

Focus on specific lines by adding a comment `[!code focus]` or by adding a
`focus` attribute after the language identifier.

<div>
  ```javascript focus={2-4}
  console.log("Line 1");
  console.log("Line 2");
  console.log("Line 3");
  console.log("Line 4");
  console.log("Line 5");
  ```
</div>

````markdown Markdown
```javascript focus={2-4}
console.log("Line 1");
console.log("Line 2");
console.log("Line 3");
console.log("Line 4");
console.log("Line 5");
```
````

### Start line

Control which line appears first in your code block by adding a `startLine` attribute after the language identifier. This is useful for longer code snippets where you want to highlight the main logic while still providing the complete context.

<div>
  ```javascript startLine={6}
      console.log("Line 1");
      console.log("Line 2");
      console.log("Line 3");
      console.log("Line 4");
      console.log("Line 5");
      console.log("Line 6");
      console.log("Line 7");
      console.log("Line 8");
      console.log("Line 9");
      console.log("Line 10");
      console.log("Line 11");
      console.log("Line 12");
      console.log("Line 13");
      console.log("Line 14");
      console.log("Line 15");
      console.log("Line 16");
      console.log("Line 17");
      console.log("Line 18");
      console.log("Line 19");
      console.log("Line 20");
      console.log("Line 21");
      console.log("Line 22");
      console.log("Line 23");
      console.log("Line 24");
      console.log("Line 25");
      console.log("Line 26");
      console.log("Line 27");
      console.log("Line 28")
  ```
</div>

````markdown Markdown
```javascript startLine={6}
console.log("Line 1");
console.log("Line 2");
console.log("Line 3");
console.log("Line 4");
console.log("Line 5");
console.log("Line 6");
console.log("Line 7");
console.log("Line 8");
console.log("Line 9");
console.log("Line 10");
console.log("Line 11");
console.log("Line 12");
console.log("Line 13");
console.log("Line 14");
console.log("Line 15");
console.log("Line 16");
console.log("Line 17");
console.log("Line 18");
console.log("Line 19");
console.log("Line 20");
console.log("Line 21");
console.log("Line 22");
console.log("Line 23");
console.log("Line 24");
console.log("Line 25");
console.log("Line 26");
console.log("Line 27");
console.log("Line 28")
```
````

### Max height

Control the max height of the code block by adding
a `maxLines` attribute after the language identifier. The
`maxLines` attribute should be a number representing the maximum
number of lines to display. By default, the code block will display up to 20 lines. (To disable the default 20 lines limit, set `maxLines` to `0`.)

When you use `maxLines`, an expand button automatically appears on hover in the top-right corner, allowing users to view the full code content in an expanded overlay that displays over the page.

<div>
  ```python maxLines=10
  def is_prime(num):
      """Check if a number is prime."""
      if num <= 1:
          return False
      for i in range(2, num):
          if num % i == 0:
              return False
      return True

  start = 10
  end = 50

  print(f"Prime numbers between {start} and {end} are:")

  prime_numbers = []

  for num in range(start, end+1):
      if is_prime(num):
          prime_numbers.append(num)

  for prime in prime_numbers:
      print(prime)
  ```
</div>

````markdown Markdown maxLines=10
```python maxLines=10
def is_prime(num):
    """Check if a number is prime."""
    if num <= 1:
        return False
    for i in range(2, num):
        if num % i == 0:
            return False
    return True

start = 10
end = 50

print(f"Prime numbers between {start} and {end} are:")

prime_numbers = []

for num in range(start, end+1):
    if is_prime(num):
        prime_numbers.append(num)

for prime in prime_numbers:
    print(prime)
```
````

<Info title="Custom styling">
  To hide the expand button or add custom styling, target the `.fern-expand-button` selector:

  ```css
  /* Hide the expand button */
  .fern-expand-button {
    display: none;
  }
  ```
</Info>

### Wrap overflow

By default, long lines that exceed the width of the code block become scrollable:

<div>
  ```txt title="Without wordWrap"
  A very very very long line of text that may cause the code block to overflow and scroll as a result.
  ```
</div>

````markdown Markdown
```txt title="Without wordWrap"
A very very very long line of text that may cause the code block to overflow and scroll as a result. 
```
````

To disable scrolling and wrap overflow onto the next line, use the `wordWrap` prop:

<div>
  ```txt title="With wordWrap" wordWrap
  A very very very long line of text that may cause the code block to overflow and scroll as a result.
  ```
</div>

````markdown Markdown
```txt title="With wordWrap" wordWrap
A very very very long line of text that may cause the code block to overflow and scroll as a result. 
```
````

### Hide line numbers

By default, code blocks display line numbers (and `$` / `>` prefixes in `bash`/`shell` code blocks) in the gutter. To hide line numbers and prefixes, set `showLineNumbers` to `false`:

<div>
  ```bash showLineNumbers={false}
  npm install plantstore
  npm run build \
      --output dist
  ```
</div>

````markdown Markdown
```bash showLineNumbers={false}
npm install plantstore
npm run build \
    --output dist
```
````

### Deep linking

Make specific text within code blocks clickable by defining a `links` map. This is useful for linking to documentation, API references, or related resources directly from your code examples.

The `links` property accepts a map where keys are matching patterns (exact strings or regex) and values are the URLs to link to.

<AccordionGroup>
  <Accordion title="Exact string matching">
    <div>
      <CodeBlock links={{"PlantClient": "/learn/docs/writing-content/demo#plantclient", "createPlant": "/learn/docs/writing-content/demo#createplant"}}>
        ```typescript
        import { PlantClient } from "@plantstore/sdk";

        const client = new PlantClient({ apiKey: "YOUR_API_KEY" });
        const plant = await client.createPlant({
          name: "Monstera",
          species: "Monstera deliciosa"
        });
        ```
      </CodeBlock>
    </div>

    ````markdown Markdown
    <CodeBlock
      links={{"PlantClient": "/learn/docs/writing-content/demo#plantclient", "createPlant": "/learn/docs/writing-content/demo#create_plant"}}
    >
    ```typescript 
    import { PlantClient } from "@plantstore/sdk";

    const client = new PlantClient({ apiKey: "YOUR_API_KEY" });
    const plant = await client.createPlant({
      name: "Monstera",
      species: "Monstera deliciosa"
    });
    ```
    </CodeBlock>
    ````

    <Note>
      The `links` property uses JSON format. Each key in the map is matched exactly against text in the code block, and matching text becomes a clickable link to the corresponding URL.
    </Note>
  </Accordion>

  <Accordion title="Regex pattern matching">
    You can use regex patterns for more flexible matching. This is useful when you want to link multiple variations or patterns of text.

    In the example below, the pattern `/get\\w+/` matches both `getPlant` and `getGarden`, while `/Plant(Store|Client)/` matches both `PlantStore` and `PlantClient`.

    <div>
      <CodeBlock links={{"/get\\w+/": "/learn/docs/writing-content/demo#get-methods", "/Plant(Store|Client)/": "/learn/docs/writing-content/demo#type-definitions"}}>
        ```python
        from plantstore import PlantStore, PlantClient

        store = PlantStore(api_key="YOUR_API_KEY")
        client = PlantClient(store)

        plant = store.getPlant(plant_id="123")
        garden = store.getGarden(garden_id="456")
        ```
      </CodeBlock>
    </div>

    ````markdown Markdown
    <CodeBlock
       links={{"/get\\w+/": "/learn/docs/writing-content/demo#get-methods", "/Plant(Store|Client)/": "/learn/docs/writing-content/demo#type-definitions"}}
    >
    ```python
    from plantstore import PlantStore, PlantClient

    store = PlantStore(api_key="YOUR_API_KEY")
    client = PlantClient(store)

    plant = store.getPlant(plant_id="123")
    garden = store.getGarden(garden_id="456")
    ```
    </CodeBlock>
    ````

    <Note>
      When using regex patterns, remember to escape special characters with double backslashes (e.g., `\\w+`, `\\d+`) in the JSON string.
    </Note>
  </Accordion>
</AccordionGroup>

### Embedding code files

You can embed code from local or external files using the `<Code>` component with the `src` prop. For local files, reference files relative to your docs directory. For external files, use full URLs to pull code samples directly from remote sources like GitHub.

The `<Code>` component supports the same props as `<CodeBlock>`, including `title`, `language`, and `maxLines`.

<div>
  ```js Local file
  console.log("I love Fern!");
  ```

  ```js title={"example-code.js"}
  console.log("I also love Fern!"); 
  ```
</div>

<div>
  ````tsx Markdown
  ```js
  console.log("I love Fern!");
  ```
  <Code src="snippets/example-code.js">
  ````
</div>

<div>
  ```yaml title={"GitHub Actions workflow (external file)"} maxLines={15}
  name: fern-check

  on:
    pull_request:
    push:
      branches:
        - main

  jobs:
    run:
      runs-on: ubuntu-latest
      steps:
        - name: Checkout repository
          uses: actions/checkout@v4

        - name: Install Fern CLI tool
          run: npm install -g fern-api

        - name: Check API is valid
          run: fern check

  ```
</div>

<div>
  ```tsx Markdown
  <Code
    src="https://raw.githubusercontent.com/fern-api/docs-starter/refs/heads/main/.github/workflows/check.yml"
    title="GitHub Actions workflow"
    language="yaml"
    maxLines={15}
  >
  ```
</div>

### Code blocks with tabs

Display multiple code blocks in a tabbed interface.

<div>
  <CodeBlocks>
    ```ruby title="hello_world.rb"
    puts "Hello World"
    ```

    ```php title="hello_world.php"
    <?php
    echo "Hello World";
    ?>
    ```

    ```rust title="hello_world.rs"
    fn main() {
        println!("Hello World");
    }
    ```
  </CodeBlocks>
</div>

````jsx Markdown
<CodeBlocks>
  ```ruby title="hello_world.rb"
  puts "Hello World"
  ```

  ```php title="hello_world.php"
  <?php
  echo "Hello World";
  ?>
  ```

  ```rust title="hello_world.rs"
  fn main() {
      println!("Hello World");
  }
  ```
</CodeBlocks>
````

## Language synchronization

Code blocks with the [same language](#supported-languages) automatically synchronize across your documentation site. When a user selects a language, all code blocks with that language switch to match. Language preferences persist across browser sessions.

<div>
  <div>
    <CodeBlocks>
      ```python title="Python"
      print("First code block!")
      ```

      ```typescript title="TypeScript"
      console.log("First code block!");
      ```

      ```go title="Go"
      fmt.Println("First code block!")
      ```

      ```csharp title="C#"
      Console.WriteLine("First code block!");
      ```

      ```java title="Java"
      System.out.println("First code block!");
      ```

      ```ruby title="Ruby"
      puts "First code block!"
      ```
    </CodeBlocks>

    <CodeBlocks>
      ```python title="Python"
      print("Second code block - syncs with the one above!")
      ```

      ```typescript title="TypeScript"
      console.log("Second code block - syncs with the one above!");
      ```

      ```go title="Go"
      fmt.Println("Second code block - syncs with the one above!")
      ```

      ```csharp title="C#"
      Console.WriteLine("Second code block - syncs with the one above!");
      ```

      ```java title="Java"
      System.out.println("Second code block - syncs with the one above!");
      ```

      ```ruby title="Ruby"
      puts "Second code block - syncs with the one above!"
      ```
    </CodeBlocks>
  </div>
</div>

<Info>
  Code blocks automatically synchronize with [tabs in that same language](/docs/writing-content/components/tabs#language-synchronization).
</Info>

<AccordionGroup>
  <Accordion title="Linking to language-specific content">
    You can link directly to content in a specific language by adding `?language=<some-language>` to the end of a URL. This sets which language tab wil be displayed by default when users visit the page.

    For example, the following link opens with Java tabs displayed: [https://buildwithfern.com/learn/docs/writing-content/components/tabs?language=java](https://buildwithfern.com/learn/docs/writing-content/components/tabs?language=java)

    This works with both `CodeBlocks` and `Tab` components that have a `language` property.
  </Accordion>

  <Accordion title="Custom synchronization">
    Use the `for` prop to create custom synchronization groups independent of language. This is useful for grouping code blocks by other criteria like package managers or frameworks.

    <div>
      <div>
        <CodeGroup>
          ```bash title="Install using npm" for="npm"
          npm install plantstore
          ```

          ```bash title="Install using pnpm" for="pnpm"
          pnpm add plantstore
          ```

          ```bash title="Install using yarn" for="yarn"
          yarn add plantstore
          ```
        </CodeGroup>

        <CodeGroup>
          ```bash title="Uninstall using npm" for="npm"
          npm uninstall plantstore
          ```

          ```bash title="Uninstall using pnpm" for="pnpm"
          pnpm remove plantstore
          ```

          ```bash title="Uninstall using yarn" for="yarn"
          yarn remove plantstore
          ```
        </CodeGroup>
      </div>
    </div>

    ````md Markdown
    <CodeGroup>
      ```bash title="Install using npm" for="npm"
      npm install plantstore
      ```
      ```bash title="Install using pnpm" for="pnpm"
      pnpm add plantstore
      ```
      ```bash title="Install using yarn" for="yarn"
      yarn add plantstore
      ```
    </CodeGroup>

    <CodeGroup>
      ```bash title="Uninstall using npm" for="npm"
      npm uninstall plantstore
      ```
      ```bash title="Uninstall using pnpm" for="pnpm"
      pnpm remove plantstore
      ```
      ```bash title="Uninstall using yarn" for="yarn"
      yarn remove plantstore
      ```
    </CodeGroup>
    ````
  </Accordion>
</AccordionGroup>

## Properties

### Code block attributes

These can be added after the language identifier in markdown code blocks or as props on the `<CodeBlock>` component.

<ParamField path="language" type="string" required={false}>
  The programming language for syntax highlighting. Supported languages: `javascript` (aliases: `js`, `node`), `python`, `java`, `typescript` (alias: `ts`), `csharp`, `cpp`, `c`, `php`, `go`, `rust`, `ruby`, `swift`, `kotlin`, `sql`, `bash` (aliases: `shell`, `sh`), `curl`, `markdown` (alias: `md`), `http`.
</ParamField>

<ParamField path="title" type="string" required={false}>
  Title displayed above the code block. Can be specified inline after the language identifier or using `title="..."` or `filename="..."` props.
</ParamField>

<ParamField path="highlight" type="string" required={false}>
  Lines to highlight, specified as `{2-4, 6}` syntax. Supports single numbers, ranges, and comma-separated lists.
</ParamField>

<ParamField path="focus" type="string" required={false}>
  Lines to focus on, specified as `focus={2-4}`. Works the same way as highlight but dims non-focused lines.
</ParamField>

<ParamField path="startLine" type="number" required={false}>
  The line number to start displaying from. Useful for showing specific portions of longer code files.
</ParamField>

<ParamField path="maxLines" type="number" required={false} default="20">
  Maximum number of lines to display before adding scrolling. Set to `0` to disable the limit.
</ParamField>

<ParamField path="wordWrap" type="boolean" required={false} default="false">
  Whether to wrap long lines instead of making them scrollable.
</ParamField>

<ParamField path="showLineNumbers" type="boolean" required={false} default="true">
  Whether to display line numbers in the gutter, including line numbers and command prompt symbols (`$` and `>`) in `bash`/`shell` code blocks. Set to `false` to hide line numbers for a cleaner look in code examples.
</ParamField>

<ParamField path="for" type="string" required={false}>
  Custom synchronization group identifier. Overrides default language-based synchronization.
</ParamField>

<ParamField path="links" type="object" required={false}>
  Map of text patterns to URLs for creating clickable links within code. Keys can be exact strings or regex patterns (e.g., `{"/get\\w+/": "/api-docs"}`).
</ParamField>

### `<Code>` properties

The `<Code>` component is used for embedding code from files. It accepts all code block attributes listed above, plus:

<ParamField path="src" type="string" required={true}>
  Path to a local file (relative to docs directory) or full URL to an external file (e.g., GitHub raw URL).
</ParamField>

<ParamField path="lines" type="number[]" required={false}>
  Lines to extract from the source file. Supports single lines (`[5]`), ranges (`[2-4]`), and combinations (`[1-3,5,7-10]`). Lines are 1-indexed.
</ParamField>