---
title: "API auto-linking"
description: "Link the names in code examples to their reference pages, with a card that shows the signature and a summary."
url: "https://ewels.github.io/starlight-codeblocks/features/api-auto-linking/"
markdown: "https://ewels.github.io/starlight-codeblocks/features/api-auto-linking.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"
---

# API auto-linking

> Link the names in code examples to their reference pages, with a card that shows the signature and a summary.

A code example uses names from libraries: modules, functions, classes and their methods. In a normal code block, a reader who wants the reference page of a name must search for it. API auto-linking finds these names and links them to their reference pages. You write nothing in the code block.

````md
```py title="report.py"
import json
from pathlib import Path

run = json.loads(Path("run.json").read_text())
print(run["status"])
```
````

The Python adapter reads the two imports. It links `json`, `pathlib`, `json.loads`, `Path` and `read_text` to the Python documentation. It knows that `read_text` belongs to `Path`, because the code calls `Path` first. Hover over a link, or move keyboard focus to it, to see a card with the kind, the name, a short summary and the source.

## Syntax

API auto-linking has no syntax. It runs on every code block in a language that has an adapter.

| Syntax | Where | Effect |
|---|---|---|
| `apiLinks=false` | Code block fence line | Turns the feature off for one code block |

## Examples

### Nextflow

A Nextflow workflow gets links for the channel factory and for the process from nf-core:

````md
```nextflow title="main.nf"
include { FASTQC } from './modules/nf-core/fastqc/main'

workflow {
    reads = channel.fromFilePairs(params.reads)
    FASTQC(reads)
}
```
````

### An adapter for your own names

A site can link its own names with an adapter of its own. This site links the names that a block imports from starlight-codeblocks:

````md
```js title="adapters.mjs"
import { nextflow } from 'starlight-codeblocks/adapters/nextflow';
import { python } from 'starlight-codeblocks/adapters/python';

export const adapters = [python(), nextflow()];
```
````

### Turn links off for one block

With `apiLinks=false`, the same Python block has no links:

````md
```py title="report.py" apiLinks=false
import json

run = json.loads(text)
```
````

## Behaviour

An adapter finds the names in a code block and resolves each one against its indexes. It links a name only when it is certain about the name. All other names stay plain text.

- Links:
  - A link has a dotted underline. On hover and on focus, the underline is solid and the link gets a faint background.
  - Names inside strings and comments never link.
- The card:
  - After 150 ms of hover, or at once on keyboard focus, a card opens under the link. It shows the signature, or the kind and the qualified name. Under that, it shows a summary, if the index has one, and the source of the link.
  - The source has the icon of its project, if [Simple Icons](https://simpleicons.org/) has one, such as Python, NumPy or Flask.
  - The card stays open while the mouse cursor is on the link or on the card. Press <kbd>Escape</kbd> to close it. The card closes when the link loses focus.
- Screen readers:
  - Screen readers get the text of the card as the description of the link.
- Copy:
  - The copied text is the same as the code. Links and cards are not part of it.
- Without JavaScript:
  - The links work, but there is no card.

Adapters load their indexes once for each build. An index that the build fetches from another site stays on disk in `node_modules/.cache/starlight-codeblocks/`, so later builds do not fetch it again. If a fetch fails and there is no copy on disk, the build logs a warning, and the names from that index stay plain text. The build does not fail.

## Options

### `apiLinks`

Links names in code to their reference pages. Set it to `false` to turn the feature off.

- Type: `false | object`
- Default: On

### `apiLinks.adapters`

Adapters that find and resolve names.

- Type: `ApiLinkAdapter[]`
- Default: `[python(), nextflow()]`

A list in `adapters` replaces the default list. To change one adapter, put all the adapters that you want in the list:

```js title="astro.config.mjs"
import codeblocks from 'starlight-codeblocks';
import { nextflow } from 'starlight-codeblocks/adapters/nextflow';
import { python } from 'starlight-codeblocks/adapters/python';

codeblocks({
  apiLinks: {
    adapters: [python({ inventories: ['https://numpy.org/doc/stable/objects.inv'] }), nextflow()],
  },
});
```

To add an adapter for another language or library, see [Write an API link adapter](https://ewels.github.io/starlight-codeblocks/extend/write-an-api-link-adapter/).

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

## Python adapter

The Python adapter runs on `py`, `python` and `pycon` code blocks. It reads `import x`, `import x as y` and `from a import b as c` in the block. Then it links the names that those imports bind, and chains of attributes on them, such as `os.path.join`.

### `stdlib`

Link names from the Python standard library, through `https://docs.python.org/3/objects.inv`.

- Type: `boolean`
- Default: `true`

### `inventories`

More Sphinx `objects.inv` files. `base` is the URL that relative links start from, if it is not the folder of `url`.

- Type: `(string | { url: string; base?: string })[]`
- Default: `[]`

### `summaries`

Fetch the documentation page of each name from an inventory, and show the first sentence of its description on the card.

- Type: `boolean`
- Default: `true`

An `objects.inv` file has no signatures and no summaries. For its names, the card shows the kind, the qualified name and the documentation that it comes from. The adapter also fetches the documentation page of each name when the site builds. It shows the first sentence of the description on the card, cut to 16 words. The page stays on disk with the inventories. If the page does not load, the card has no summary, and the build shows no warning.

If the site also uses starlight-pydocs, install both plugins. The Python adapter then links the names of every package that starlight-pydocs documents, with no configuration:

```js title="astro.config.mjs"
starlight({
  plugins: [starlightPydocs({ packages: [{ name: 'myproject' }] }), codeblocks()],
});
```

For these names, the card has the signature and the first sentence of the docstring, as starlight-pydocs shows them. A name links to the site's own page, also if an inventory has the same name. Names that a package re-exports, such as `myproject.Report` from a private `myproject._report` module, link to the object's page. If starlight-pydocs documents one package at two bases, such as the current version and an older one, the first entry in its `packages` list wins.

To link a block to another version, set `pydocsBase` to the `base` of that package. starlight-pydocs sets it on the examples in its docstrings, so that each version links to its own pages. You can also set it on a block that you write:

````md
```py pydocsBase="1x/api/myproject"
from myproject import Report
```
````

A name that the package at `pydocsBase` does not have links to the first package that has it, or to an inventory. If no package has the base, the build shows a warning, and the block links as it does without the attribute.

## Nextflow adapter

The Nextflow adapter runs on `nextflow` and `nf` code blocks. It has the channel factories and operators of the Nextflow reference, so it needs no network. It links:

- Channel factories, such as `channel.of` and `channel.fromPath`.
- Operators in a chain after a channel factory, such as `.map` and `.view`.
- Operators on a variable that holds a channel in every assignment in the block.
- Processes and workflows from `include` statements, if you give the `modules` option.

### `modules`

The reference page of an included process or workflow.

- Type: `({ name, path }) => string | object | undefined`
- Default: None

`modules` gets the name in the module and the path after `from`. It returns the URL of the page, or an object with `href` and, if you want them, `kind`, `signature`, `summary` and `source`. It returns `undefined` for a name that must stay plain text. This site links nf-core modules to their pages on the nf-core site:

```js title="astro.config.mjs"
nextflow({
  modules: ({ name }) => ({
    href: `https://nf-co.re/modules/${name.toLowerCase()}`,
    kind: 'process',
    source: 'nf-core modules',
  }),
});
```

## Limitations

- The Python adapter does not follow assignments. After `p = Path("run.json")`, the name `p.read_text` stays plain text.
- The Python adapter does not link built-in names, such as `print` and `len`.
- A name that the block binds again, for example with `json = {}` or as a function parameter, does not link anywhere in the block.
- The Nextflow adapter does not link operators after a process output, such as `FASTQC.out.html.map`, or after the `|` operator.
- The files in `node_modules/.cache/starlight-codeblocks/` do not expire. Delete the folder to fetch the indexes again.
- A link cannot span two lines.
- Names on the line that a `[!link]` directive targets do not link, so that a link is never inside another link.

## Related

- [Code links](https://ewels.github.io/starlight-codeblocks/features/code-links/): link one piece of text to a URL that you choose. Use them for names that no adapter knows.
- [Write an API link adapter](https://ewels.github.io/starlight-codeblocks/extend/write-an-api-link-adapter/): add links for another language or library.
