---
title: "Code links"
description: "Turn text in code into a link with a card that describes it, from a directive in the comment above."
url: "https://ewels.github.io/starlight-codeblocks/features/code-links/"
markdown: "https://ewels.github.io/starlight-codeblocks/features/code-links.md"
section: "Link code"
site: "starlight-codeblocks documentation"
context: "This page is from the documentation of starlight-codeblocks. A Starlight plugin that adds focus, line states, annotations, API auto-linking and 22 more features to the code blocks of a site."
index: "https://ewels.github.io/starlight-codeblocks/llms.txt"
---

# Code links

> Turn text in code into a link with a card that describes it, from a directive in the comment above.

Readers who meet an unfamiliar function in an example often want to know what it does, and where its reference page is. A code block in Starlight has no links, so the reader must search for it. The `[!link]` directive turns text on a line into a link to the page you choose, with a short description in a card.

````md
```py
import numpy as np

# [!link /linspace/ https://numpy.org/doc/stable/reference/generated/numpy.linspace.html] Returns evenly spaced numbers over an interval.
x = np.linspace(0, 1, 50)
y = np.sin(2 * np.pi * x)
```
````

The directive is on its own line, above the line it applies to. It can also go at the end of that line. The plugin removes the directive, and `linspace` becomes a link with an underline in the accent colour. Hover over the link, or press Tab to focus it, to see the description in a card. The rest of the line keeps its syntax colours.

## Syntax

| Syntax | Where |
|---|---|
| `[!link /<text>/ <url>] <description>` | Comment on or above the line |
| `[!link /<text>/ <url>]` | Comment on or above the line |

`<text>` is literal text, not a regular expression. The plugin links its first match on the line it applies to. `<url>` is a relative, `http` or `https` URL without spaces. A URL that starts with `/` is a link inside the site.

`<description>` is optional. It shows in a card, as for [API auto-linking](https://ewels.github.io/starlight-codeblocks/features/api-auto-linking/). The text runs to the next directive or to the end of the comment. Without a description, the link has no card.

Several `[!link]` lines can stack above one line of code, one for each text to link.

## Examples

### Two links on one line

Two `[!link]` lines above one line link two names on it, each with its own card:

````md
```py title="notes.py"
from pathlib import Path

# [!link /Path/ https://docs.python.org/3/library/pathlib.html#pathlib.Path] A path on the file system.
# [!link /read_text/ https://docs.python.org/3/library/pathlib.html#pathlib.Path.read_text] Returns the text of the file.
notes = Path("notes.txt").read_text()
```
````

### A link inside the site

A link inside the site starts with `/`. The plugin adds the site's base:

````md
```js title="astro.config.mjs"
export default defineConfig({
  // [!link /codeblocks/ /reference/options/] Every option of the plugin.
  integrations: [starlight({ plugins: [codeblocks()] })],
});
```
````

### Links without a description

Leave out the description for a plain link with no card. It needs no JavaScript:

````md
```py
import numpy as np

# [!link /linspace/ https://numpy.org/doc/stable/reference/generated/numpy.linspace.html]
x = np.linspace(0, 1, 50)
```
````

## Behaviour

- The link:
  - The linked text keeps its syntax colours, with an underline in the accent colour. Hover over the link to see a faint background.
  - The link is a normal link. Readers can focus it with the keyboard, and it opens in the same tab.
  - A URL that starts with `/` gets Astro's `base` in front of it, unless it already starts with the base. On this site, `/reference/directives/` becomes `/starlight-codeblocks/reference/directives/`. A site without `codeblocks()` gives the base to `pluginCodeblocks()`, as the [Expressive Code plugins page](https://ewels.github.io/starlight-codeblocks/reference/expressive-code-plugins/#the-preset) shows.
- The card:
  - The card shows on hover and on focus. It shows the linked text, the description and the domain of the URL. A link inside the site shows no domain. Press Escape to close the card.
  - The card shows plain text. Inline code, bold and links in the description become plain text.
- Screen readers:
  - Screen readers read the description and the domain as the link's description.
- Copy:
  - The copied text leaves out the directive line.
- Warnings:
  - If the text has no match on the line it applies to, the build logs a warning and the line renders without the link. A directive without a URL, or with another scheme such as `mailto:`, gets a warning too.
- Without JavaScript:
  - The card needs JavaScript, and the page loads it only for a block with a description. Without JavaScript, the link still works.

## Options

Code links have no options. Turn the feature off for the whole site with `codeLinks: false`:

```js title="astro.config.mjs"
codeblocks({
  codeLinks: false,
});
```

With `codeLinks: false`, a `[!link]` directive is an unknown directive. The build logs a warning and leaves the comment in the code.

- [Configuration](https://ewels.github.io/starlight-codeblocks/configuration/): Learn how to set options for the whole site, or for a single code block.

## Limitations

- A directive links the first match only. To link a later match, make the text longer, so that it matches only there.
- Languages with no comment syntax, such as JSON, cannot use `[!link]`. Use `jsonc` instead.
- A link cannot span two lines.

## Related

- [API auto-linking](https://ewels.github.io/starlight-codeblocks/features/api-auto-linking/): link every name that an adapter knows, with no directive in the code. Code links are for one-off links.
- [Comment notation](https://ewels.github.io/starlight-codeblocks/comment-notation/): the directive syntax that `[!link]` uses.
