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.
Readers see
import numpy as np
y = np.sin(2 * np.pi * x)You write
```pyimport 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
Section titled “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. 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
Section titled “Examples”Two links on one line
Section titled “Two links on one line”Two [!link] lines above one line link two names on it, each with its own card:
```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
Section titled “A link inside the site”A link inside the site starts with /. The plugin adds the site’s base:
export default defineConfig({});```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
Section titled “Links without a description”Leave out the description for a plain link with no card. It needs no JavaScript:
import numpy as np
```pyimport numpy as np
# [!link /linspace/ https://numpy.org/doc/stable/reference/generated/numpy.linspace.html]x = np.linspace(0, 1, 50)```Behaviour
Section titled “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’sbasein front of it, unless it already starts with the base. On this site,/reference/directives/becomes/starlight-codeblocks/reference/directives/. A site withoutcodeblocks()gives the base topluginCodeblocks(), as the Expressive Code plugins page 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.
- 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
- 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
Section titled “Options”Code links have no options. Turn the feature off for the whole site with codeLinks: false:
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.
Limitations
Section titled “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]. Usejsoncinstead. - A link cannot span two lines.
Related
Section titled “Related”- 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: the directive syntax that
[!link]uses.