Code block

View as Markdown

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.

Supported languages

Fern supports Shiki syntax highlighting for the following languages:

  • curl
  • python
  • javascript (aliases: js, node)
  • typescript (aliases: ts)
  • go
  • ruby
  • csharp
  • php
  • swift
  • rust

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

Usage

Use three backticks with an optional language identifier.

1console.log("hello world")
Markdown
1```js
2console.log("hello world")
3```

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.

Snippet with title
1console.log("hello world")
Markdown
1```js Snippet with title
2console.log("hello world")
3```

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.

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

Line focusing

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

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

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.

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

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.

1def is_prime(num):
2 """Check if a number is prime."""
3 if num <= 1:
4 return False
5 for i in range(2, num):
6 if num % i == 0:
7 return False
8 return True
9
10start = 10
11end = 50
12
13print(f"Prime numbers between {start} and {end} are:")
14
15prime_numbers = []
16
17for num in range(start, end+1):
18 if is_prime(num):
19 prime_numbers.append(num)
20
21for prime in prime_numbers:
22 print(prime)
Markdown
1```python maxLines=10
2def is_prime(num):
3 """Check if a number is prime."""
4 if num <= 1:
5 return False
6 for i in range(2, num):
7 if num % i == 0:
8 return False
9 return True
10
11start = 10
12end = 50
13
14print(f"Prime numbers between {start} and {end} are:")
15
16prime_numbers = []
17
18for num in range(start, end+1):
19 if is_prime(num):
20 prime_numbers.append(num)
21
22for prime in prime_numbers:
23 print(prime)
24```
Custom styling

To hide the expand button or add custom styling, target the .fern-expand-button selector:

1/* Hide the expand button */
2.fern-expand-button {
3 display: none;
4}

Wrap overflow

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

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

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

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

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.

1import { PlantClient } from "@plantstore/sdk";
2
3const client = new PlantClient({ apiKey: "YOUR_API_KEY" });
4const plant = await client.createPlant({
5 name: "Monstera",
6 species: "Monstera deliciosa"
7});
Markdown
1<CodeBlock
2 links={{"PlantClient": "/learn/docs/writing-content/demo#plantclient", "createPlant": "/learn/docs/writing-content/demo#create_plant"}}
3>
4```typescript
5import { PlantClient } from "@plantstore/sdk";
6
7const client = new PlantClient({ apiKey: "YOUR_API_KEY" });
8const plant = await client.createPlant({
9 name: "Monstera",
10 species: "Monstera deliciosa"
11});
12```
13</CodeBlock>

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.

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.

1from plantstore import PlantStore, PlantClientfrom plantstore import PlantStore, PlantClient
2
3store = PlantStore(api_key="YOUR_API_KEY")
4client = PlantClient(store)
5
6plant = store.getPlant(plant_id="123")
7garden = store.getGarden(garden_id="456")
Markdown
1<CodeBlock
2 links={{"/get\\w+/": "/learn/docs/writing-content/demo#get-methods", "/Plant(Store|Client)/": "/learn/docs/writing-content/demo#type-definitions"}}
3>
4```python
5from plantstore import PlantStore, PlantClient
6
7store = PlantStore(api_key="YOUR_API_KEY")
8client = PlantClient(store)
9
10plant = store.getPlant(plant_id="123")
11garden = store.getGarden(garden_id="456")
12```
13</CodeBlock>

When using regex patterns, remember to escape special characters with double backslashes (e.g., \\w+, \\d+) in the JSON string.

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.

Local file
1console.log("I love Fern!");
example-code.js
1console.log("I also love Fern!");
Markdown
1```js
2console.log("I love Fern!");
3```
4<Code src="snippets/example-code.js">
GitHub Actions workflow (external file)
1name: fern-check
2
3on:
4 pull_request:
5 push:
6 branches:
7 - main
8
9jobs:
10 run:
11 runs-on: ubuntu-latest
12 steps:
13 - name: Checkout repository
14 uses: actions/checkout@v4
15
16 - name: Install Fern CLI tool
17 run: npm install -g fern-api
18
19 - name: Check API is valid
20 run: fern check
Markdown
1<Code
2 src="https://raw.githubusercontent.com/fern-api/docs-starter/refs/heads/main/.github/workflows/check.yml"
3 title="GitHub Actions workflow"
4 language="yaml"
5 maxLines={15}
6>

Code blocks with tabs

Display multiple code blocks in a tabbed interface.

1puts "Hello World"
Markdown
1<CodeBlocks>
2 ```ruby title="hello_world.rb"
3 puts "Hello World"
4 ```
5
6 ```php title="hello_world.php"
7 <?php
8 echo "Hello World";
9 ?>
10 ```
11
12 ```rust title="hello_world.rs"
13 fn main() {
14 println!("Hello World");
15 }
16 ```
17</CodeBlocks>

Language synchronization

Code blocks with the same language 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.

1print("First code block!")
1print("Second code block - syncs with the one above!")

Code blocks automatically synchronize with tabs in that same language.

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

This works with both CodeBlocks and Tab components that have a language property.

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.

$npm install plantstore
$npm uninstall plantstore
Markdown
1<CodeGroup>
2 ```bash title="Install using npm" for="npm"
3 npm install plantstore
4 ```
5 ```bash title="Install using pnpm" for="pnpm"
6 pnpm add plantstore
7 ```
8 ```bash title="Install using yarn" for="yarn"
9 yarn add plantstore
10 ```
11</CodeGroup>
12
13<CodeGroup>
14 ```bash title="Uninstall using npm" for="npm"
15 npm uninstall plantstore
16 ```
17 ```bash title="Uninstall using pnpm" for="pnpm"
18 pnpm remove plantstore
19 ```
20 ```bash title="Uninstall using yarn" for="yarn"
21 yarn remove plantstore
22 ```
23</CodeGroup>

Properties

Code block attributes

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

language
string

The programming language for syntax highlighting. Supported languages include: curl, python, javascript, typescript, go, ruby, csharp, php, swift, rust.

title
string

Title displayed above the code block. Can be specified inline after the language identifier or using title="..." or filename="..." props.

highlight
string

Lines to highlight, specified as {2-4, 6} syntax. Supports single numbers, ranges, and comma-separated lists.

focus
string

Lines to focus on, specified as focus={2-4}. Works the same way as highlight but dims non-focused lines.

startLine
number

The line number to start displaying from. Useful for showing specific portions of longer code files.

maxLines
numberDefaults to 20

Maximum number of lines to display before adding scrolling. Set to 0 to disable the limit.

wordWrap
booleanDefaults to false

Whether to wrap long lines instead of making them scrollable.

for
string

Custom synchronization group identifier. Overrides default language-based synchronization.

<CodeBlock> properties

The <CodeBlock> component accepts all the attributes above as props, plus:

links
object

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"}).

<Code> properties

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

src
stringRequired

Path to a local file (relative to docs directory) or full URL to an external file (e.g., GitHub raw URL).

lines
number[]

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.