Skip to content

Internationalisation

The generated pages render many labels: section headings such as Parameters and Returns, badges, table columns, the search box, and the permalink hint. Each label comes from a translation table, not from your docstrings. The package ships with thirteen languages, and you don’t need to configure anything to use them.

The translation mechanism depends on the host. Under Starlight, the labels come from Starlight’s own translation system, and the plugin injects its tables into it. A plain Astro project has no translation system, so its components take a labels prop instead. This is why <Autodoc>, <SymbolSearch> and the other components have label props.

Locale Language Locale Language
en English (the source) nl Dutch
de German no Norwegian (Bokmål)
es Spanish pt-BR Portuguese (Brazil)
fr French ru Russian
it Italian sv Swedish
ja Japanese zh Chinese (simplified)
ko Korean

Each locale overlays only the keys it translates. English fills any gap, so a string added in a new release is readable everywhere from the day it lands.

Labels that name a Python or pydantic construct stay in English in every locale: classmethod, staticmethod, async, abstract, cached, pydantic model, pydantic field and pydantic validator. These are the identifiers a reader sees in the code, and translating them would name something that does not exist.

The plugin injects its tables through Starlight’s i18n:setup hook. Labels then follow Starlight’s own locale selection, with no extra configuration needed. A site with locales configured serves each locale’s pages with that locale’s labels. A monolingual site with defaultLocale: 'fr' gets French labels throughout.

astro.config.mjs
import starlight from '@astrojs/starlight';
import { defineConfig } from 'astro/config';
import starlightPydocs from 'starlight-pydocs';
export default defineConfig({
integrations: [
starlight({
title: 'Mon projet',
defaultLocale: 'fr',
locales: { fr: { label: 'Français' }, en: { label: 'English' } },
plugins: [starlightPydocs({ packages: [{ name: 'mypkg', search: ['../src'] }] })],
}),
],
});

The generated pages themselves are not translated. There is one set of API pages, built from one dump, and each page carries the labels of whichever locale the reader is browsing. The docstrings stay in whatever language you wrote them in.

The keys share Starlight’s global translation table, namespaced starlightPydocs.. Overriding one key works the same as overriding any Starlight string. Starlight reads these overrides from an i18n collection. A site that has never translated anything will not have declared this collection yet:

src/content.config.ts
import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders';
import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';
import { defineCollection } from 'astro:content';
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() }),
};

One JSON file per locale overrides whichever keys you name. The schema accepts keys it does not recognise, so plugin keys need no extra declaration:

src/content/i18n/fr.json
{
"starlightPydocs.parameters": "Arguments",
"starlightPydocs.viewSource": "Voir le code"
}

Use the same file to add a locale the package does not ship yet. If you translate a full set of strings, please send a pull request that adds it to translations.ts. See Contributing.

A plain Astro project has no translation table to inject into. Every component that renders a label takes a labels prop instead, carrying whichever keys you want to override. This prop wins over every other source, and you can also use it to override one string in one place inside a Starlight site:

src/pages/report.astro
---
import { Autodoc, SymbolSearch } from 'starlight-pydocs/components';
---
<Autodoc
name="mypkg.Report"
labels={{ parameters: 'Arguments', returns: 'Retourne', viewSource: 'Voir le code' }}
/>
<SymbolSearch
labels={{ searchLabel: 'Rechercher un symbole', searchPlaceholder: 'Classes, fonctions, attributs…' }}
/>

In a vanilla site, the route renders the generated pages, not you, so there is no labels prop to pass them. Instead, they read a translation function off Astro.locals. This is the same mechanism Starlight’s t() arrives through, so one middleware can translate every generated page:

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
const fr: Record<string, string> = {
'starlightPydocs.parameters': 'Arguments',
'starlightPydocs.viewSource': 'Voir le code',
'starlightPydocs.onPage': 'Sur cette page',
};
export const onRequest = defineMiddleware((context, next) => {
context.locals.t = (key: string) => fr[key] ?? key;
return next();
});

Keys are namespaced exactly as in a Starlight table. Returning the key unchanged means “no translation” and falls back to English. Without this middleware, a vanilla site’s generated pages use the English defaults.

locals.t is your own addition to App.Locals. Declare it once for the type-checker:

src/env.d.ts
declare namespace App {
interface Locals {
t: (key: string) => string;
}
}

Every label resolves in this order: the labels prop, then the host’s translation for starlightPydocs.<key>, then the bundled English default below. lib/strings.ts in the package holds the full list of keys, and the unit tests check that every locale’s keys exist in it.

Member group headings, for the sections listing what a module or class contains:

Key English default
attributes Attributes
properties Properties
classes Classes
functions Functions
methods Methods
modules Modules
typeAliases Type aliases

Docstring section headings, one per section Griffe parses out of a docstring:

Key English default
parameters Parameters
otherParameters Other parameters
typeParameters Type parameters
returns Returns
yields Yields
receives Receives
raises Raises
warns Warns
examples Examples

Signature and member metadata:

Key English default
bases Bases
default default
required required
inheritedFrom Inherited from
reexportedFrom Re-exported from
aliasOf Alias of
deprecated Deprecated
deprecatedSince Deprecated since
addedIn Added in
viewSource View source
openDocsAt Open docs at
showMore Show more
showLess Show less

openDocsAt is the tooltip on an annotation that links to another documentation site, followed by that site’s host name. showMore and showLess label the toggle under an attribute value too long to show whole.

Table columns, used by the parameter and attribute tables:

Key English default
columnName Name
columnType Type
columnDescription Description
columnDefault Default

Object kinds, for badges and for grouping symbol search results:

Key English default
kindModule module
kindClass class
kindFunction function
kindMethod method
kindAttribute attribute
kindProperty property
kindAlias alias

Badges for the labels Griffe attaches to an object. The first five keys and the three pydantic keys are the constructs named above. No locale translates them:

Key English default
labelClassmethod classmethod
labelStaticmethod staticmethod
labelAsync async
labelAbstract abstract
labelCached cached
labelReadOnly read-only
labelWritable writable
labelInstanceAttribute instance attribute
labelClassAttribute class attribute
labelModuleAttribute module attribute
labelPydanticModel pydantic model
labelPydanticField pydantic field
labelPydanticValidator pydantic validator

Symbol search, the plugin’s own search box. See Search:

Key English default
searchLabel Search symbols
searchPlaceholder Search classes, functions, attributes…
searchNoResults No matching symbols
searchResults Results
searchHint Type part of a name or a dotted path

Page furniture: the strings around the objects rather than on them. permalink is the accessible name of an anchor heading’s link, followed by the object path. overview is the sidebar link to a package’s root page:

Key English default
permalink Permalink to
overview Overview
onPage On this page
noMembers No documented members.
undocumented No description.