UNPKG

@astrojs/starlight

Version:

Build beautiful, high-performance documentation websites with Astro

59 lines (53 loc) 2.51 kB
import { getCollection, type CollectionEntry, type DataCollectionKey } from 'astro:content'; import config from 'virtual:starlight/user-config'; import project from 'virtual:starlight/project-context'; import pluginTranslations from 'virtual:starlight/plugin-translations'; import type { i18nSchemaOutput } from '../schemas/i18n'; import { createTranslationSystem } from './createTranslationSystem'; import type { RemoveIndexSignature } from './types'; import { getCollectionPathFromRoot } from './collection'; import { stripExtension, stripLeadingSlash } from './path'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - This may be a type error in projects without an i18n collection and running // `tsc --noEmit` in their project. Note that it is not possible to inline this type in // `UserI18nSchema` because this would break types for users having multiple data collections. type i18nCollection = CollectionEntry<'i18n'>; const i18nCollectionPathFromRoot = getCollectionPathFromRoot('i18n', project); export type UserI18nSchema = 'i18n' extends DataCollectionKey ? i18nCollection extends { data: infer T } ? i18nSchemaOutput & T : i18nSchemaOutput : i18nSchemaOutput; export type UserI18nKeys = keyof RemoveIndexSignature<UserI18nSchema>; /** Get all translation data from the i18n collection, keyed by `lang`, which are BCP-47 language tags. */ async function loadTranslations() { // Briefly override `console.warn()` to silence logging when a project has no i18n collection. const warn = console.warn; console.warn = () => {}; const userTranslations: Record<string, UserI18nSchema> = Object.fromEntries( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore — may be a type error in projects without an i18n collection (await getCollection('i18n')).map(({ id, data, filePath }) => { const lang = project.legacyCollections || !filePath ? id : stripExtension(stripLeadingSlash(filePath.replace(i18nCollectionPathFromRoot, ''))); return [lang, data] as const; }) ); // Restore the original warn implementation. console.warn = warn; return userTranslations; } /** * Generate a utility function that returns UI strings for the given language. * @param {string | undefined} [lang] * @example * const t = useTranslations('en'); * const label = t('search.label'); // => 'Search' */ export const useTranslations = await createTranslationSystem( config, await loadTranslations(), pluginTranslations );