# General Translation Integrations: Extension API
URL: https://generaltranslation.com/en-US/docs/integrations/paraglide/reference/extension-api.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Customize what counts as Paraglide JS, which file formats are analyzed, and how imports are resolved. API reference for the targets, languages, bundler configs, and resolvers.

Everything on this page is exported from `@generaltranslation/paraglide-js/compiler` and passed to [`collectContext`](/docs/integrations/paraglide/reference/collect-context) through its options. The analysis itself (module graph, usages, and rendering) is internal.

## Overview [#overview]

| API | Description |
| --- | --- |
| [Targets](#targets) | Which resolved files belong to Paraglide JS and what their exports are. |
| [Languages](#languages) | File formats converted to TypeScript by a framework's tooling. |
| [Bundler configs](#bundler-configs) | Config files that import aliases are read from. |
| [Resolvers](#resolvers) | Functions that resolve an import to a file, and the collector they plug into. |

## Targets [#targets]

A target says which resolved files belong to Paraglide JS and what each of their exports is. Pass targets with the [`targets`](/docs/integrations/paraglide/reference/collect-context#targets) option. When several match a file, the last one wins.

```ts
type ParaglideTarget = {
  name: string; // label on usages, such as "message"
  matches(file: TargetFile): boolean;
  // Return undefined to not track an export.
  exportSymbol(exportName: string, file: TargetFile): SymbolSpec | undefined;
};

type TargetFile = {
  file: string; // absolute, with forward slashes
  outdir: string | undefined; // the output directory that contains the file
  outdirPath: string | undefined; // relative to outdir, such as "messages.js"
};

type SymbolSpec =
  | { type: 'namespace'; member(name: string): SymbolSpec | undefined }
  // methods: methods whose calls also count, such as .parts() on messages
  | { type: 'value'; name: string; methods?: readonly string[] };
```

| Export | Description |
| --- | --- |
| `defaultTargets` | `messagesTarget`, `runtimeTarget`, `serverTarget`, `registryTarget`, and `adapterTargets`. |
| `messagesTarget` | `messages.js`, with its `m` namespace, and every module in `messages/`. Named `message`. |
| `runtimeTarget`, `serverTarget`, `registryTarget` | Every export of `runtime.js`, `server.js`, and `registry.js`. |
| `adapterTargets` | Paraglide's framework adapters: `@inlang/paraglide-js-react`, `-solid`, `-svelte`, and `-vue`, and Paraglide JS 1's `@inlang/paraglide-sveltekit`, `@inlang/paraglide-next`, and `@inlang/paraglide-astro`. |
| `defineTarget(target)` | Returns the target unchanged, typed as a `ParaglideTarget`. |
| `generatedFileTarget(name, outdirPath)` | A file in the output directory whose every export is tracked. |
| `packageTarget(name, packageName)` | An installed package whose named exports are tracked. |

*Note: Only usages of the `message` target are written to [metadata files](/docs/integrations/paraglide/reference/metadata-files). Usages of other targets are analyzed but have no message key to be written under.*

## Languages [#languages]

A language converts a file format to one JavaScript or TypeScript module with the framework's own tooling. Pass languages with the [`languages`](/docs/integrations/paraglide/reference/collect-context#languages) option. (See [Adding file formats](/docs/integrations/paraglide/guides/adding-file-formats)).

```ts
type SourceLanguage = {
  name: string;
  extensions: readonly string[];
  // Required to claim script extensions, such as Angular components in .ts files.
  detect?(source: string, file: string): boolean;
  // The packages it needs in the app, named when one is missing.
  requires?: readonly string[];
  // The package that brings a required one: { svelte2tsx: 'svelte-check' }.
  installedWith?: Readonly<Record<string, string>>;
  // Return undefined when the tooling is not installed; throw when it rejects
  // the file. Either way the file is skipped.
  generate(
    source: string,
    file: string,
    context: LanguageContext
  ): GeneratedSource | undefined | Promise<GeneratedSource | undefined>;
};

type LanguageContext = {
  // Imports a package installed in the app; undefined if it is not installed.
  load<T = unknown>(specifier: string): Promise<T | undefined>;
};

type ParseLang = 'js' | 'jsx' | 'ts' | 'tsx';
```

### Generated source

`generate` returns a `GeneratedSource`. Code without a mapping never counts as a usage.

| Field | Description | Type | Optional |
| --- | --- | --- | --- |
| `code` | The file as one module. | `string` | No |
| `lang` | The language of `code`. | `ParseLang` | No |
| `mappings` | Where each range of `code` comes from in the file. | `Mapping[]` | No |
| `elements` | The file's markup, which labels each usage with its element. The label is not written to metadata files. | `SourceElement[]` | Yes |
| `scripts` | Modules of their own in the file, such as an Astro page's client scripts, each as a `GeneratedScript`: `{ code, lang, mappings }`. | `GeneratedScript[]` | Yes |
| `componentFields` | Classes whose fields a template reads undeclared, as Angular templates do. Each is a `ComponentFields`: `{ specifier, className?, range? }`. | `ComponentFields[]` | Yes |
| `scopeObjects` | Objects whose members resolve like names of the module, such as Vue's `__VLS_ctx`. | `string[]` | Yes |
| `props` | Where the component reads the props its call sites pass: `{ calls?, members?, variables?, undeclared? }`. | `object` | Yes |
| `componentInstances` | How the generated code renders imported components besides JSX: `{ via: 'new' \| 'call', path }`. | `object` | Yes |

### Mappings and elements

```ts
// Generated [generated, generated + length) stands for
// source [source, source + sourceLength). sourceLength defaults to length.
type Mapping = {
  generated: number;
  source: number;
  length: number;
  sourceLength?: number;
};

// From a version 3 source map, such as svelte2tsx's: the map as an object
// (EncodedSourceMap of @jridgewell/trace-mapping) or as a JSON string.
function mappingsFromSourceMap(
  map: EncodedSourceMap | string,
  generatedCode: string,
  sourceCode: string
): Mapping[];

// From the mappings of Volar's virtual code:
// @vue/language-core, @mdx-js/language-service, Glint.
// Pass Volar's mappings as they are.
function mappingsFromVolar(
  mappings: readonly {
    sourceOffsets: readonly number[];
    generatedOffsets: readonly number[];
    lengths: readonly number[];
    generatedLengths?: readonly number[];
  }[]
): Mapping[];
```

A `SourceElement` describes one markup element with source offsets: `name`, `start`, `end`, `nameStart`, `nameEnd`, `openEnd`, `component`, and `attributes` (each `{ name, start, end }`, where the range is the attribute's value).

### Built-in languages

`defaultLanguages` holds, in order: `vueLanguage`, `svelteLanguage`, `astroLanguage`, `mdxLanguage`, `markdownLanguage`, `angularComponentLanguage`, `angularTemplateLanguage`, `analogLanguage`, `markoLanguage`, and `emberLanguage`. Each is also exported on its own. For the files and tools of each, see [Supported file formats](/docs/integrations/paraglide/reference/file-formats).

## Bundler configs [#bundler-configs]

A bundler config reads import aliases from a config file without running the bundler. Pass them with the [`bundlerConfigs`](/docs/integrations/paraglide/reference/collect-context#bundler-configs) option. (See [Resolving imports](/docs/integrations/paraglide/guides/resolving-imports#bundler-config)).

```ts
type BundlerConfig = {
  name: string;
  files: readonly string[]; // possible config file names
  // file is absolute. A failure, returned or thrown, is reported and the
  // config is skipped.
  read(
    file: string,
    context: ConfigContext
  ): Promise<ImportResolution | ConfigFailure>;
};

type ImportResolution = {
  aliases: readonly ImportAlias[];
  rootDirectory?: string; // where /src/a.js resolves from (Vite's root)
};

type ConfigFailure = { error: string };

type ConfigContext = {
  // Imports a package from the app; undefined if it is not installed.
  load<T = unknown>(specifier: string): Promise<T | undefined>;
};

type ImportAlias = {
  find: string | RegExp; // a string matches find and find/…
  replacement: string;
  exact?: boolean; // a string matches only find itself (webpack's name$)
};

type AliasOption = Readonly<Record<string, string>> | readonly ImportAlias[];
```

| Export | Description |
| --- | --- |
| `defaultBundlerConfigs` | `viteConfig`, `webpackConfig`, and `rspackConfig`, in that order. |
| `viteConfig` | Reads `vite.config.*` with the app's own Vite. Returns the resolved aliases and Vite's root. |
| `webpackConfig`, `rspackConfig` | Import `webpack.config.*` and `rspack.config.*` and read `resolve.alias`. |
| `webpackLikeConfig(name, baseName)` | Makes a bundler config for a file in webpack's format named `baseName` with a `.js`, `.mjs`, `.ts`, `.cjs`, `.mts`, or `.cts` extension. |

A webpack-format config can export an object, a function, or a list of either; the first entry of a list is used. A function is called with an empty `env` and `{ mode: 'production' }`.

## Resolvers [#resolvers]

A resolver returns the file an import resolves to, or `undefined`. To use your own, create the collector that [`collectContext`](/docs/integrations/paraglide/reference/collect-context) wraps. (See [Resolving imports](/docs/integrations/paraglide/guides/resolving-imports#custom-resolver)).

```ts
type Resolver = (
  specifier: string,
  importer: string
) => Promise<string | undefined>;

function createCollector(
  options: ParaglideContextOptions,
  environment: CollectorEnvironment
): ContextCollector;

type CollectorEnvironment = {
  root: string; // the project, or a directory in it
  logger: CollectorLogger; // { warn(message), info(message) }
  resolver: Resolver;
};
```

`ParaglideContextOptions` holds the options of `collectContext` that do not concern resolution: `include`, `exclude`, `targets`, `languages`, `inlangProjects`, `radius`, `outdirs`, and `autoImports`. On the returned `ContextCollector`, call `scanAll()` to analyze the project, then `write()` to write the metadata files.

| Export | Description |
| --- | --- |
| `nodeResolver(options?)` | Resolves like a bundler without one: aliases, package `exports` and `imports`, `tsconfig.json` `paths` from the nearest `tsconfig.json` of each importer, and TypeScript's `./a.js` to `./a.ts`. Takes `NodeResolverOptions`: `{ alias?, rootDirectory?, conditions? }`. |
| `ProjectResolver` | The resolver `collectContext` uses: the aliases of the app's bundler config, then `nodeResolver`. |

```ts
import {
  createCollector,
  ProjectResolver,
} from '@generaltranslation/paraglide-js/compiler';

const environment = { root: process.cwd(), logger: console };
// ProjectResolverOptions: NodeResolverOptions and bundlerConfigs
const resolver = new ProjectResolver({ alias: { '~': '/app/src' } }, environment);

const collector = createCollector(
  { include: ['src'] },
  { ...environment, resolver: resolver.resolve }
);

await collector.scanAll();
await collector.write();
await resolver.warnUnresolved(); // lists imports that may be undeclared aliases
```

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
