# General Translation Integrations: Adding file formats
URL: https://generaltranslation.com/en-US/docs/integrations/paraglide/guides/adding-file-formats.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: How to analyze component files in a format the built-in languages do not cover.

Files that are not JavaScript, TypeScript, or JSX are converted to TypeScript by a language: a small adapter around the framework's own tooling. Add a language when your app uses messages in a format that is missing from the [supported file formats](/docs/integrations/paraglide/reference/file-formats).

Languages are a library option, so this guide uses [`collectContext`](/docs/integrations/paraglide/reference/collect-context) instead of the CLI.

## Before you start [#before-start]

You need a compiler or language tool for the format which returns:

- The file as JavaScript or TypeScript code.
- A source map, or Volar mappings, from that code back to the file.

Code without a mapping never counts as a usage, so the mappings decide which usages are found and where their context is cut.

## Write the language [#write-language]

A [`SourceLanguage`](/docs/integrations/paraglide/reference/extension-api#languages) names its file extensions and the packages it needs, and returns the generated module:

```ts title="riot-language.ts"
import {
  mappingsFromSourceMap,
  type SourceLanguage,
} from '@generaltranslation/paraglide-js/compiler';

export const riotLanguage: SourceLanguage = {
  name: 'riot',
  extensions: ['.riot'],
  requires: ['@riotjs/compiler'], // named in the warning when missing
  async generate(source, file, context) {
    // Loaded from the app; undefined if it is not installed.
    const compiler =
      await context.load<typeof import('@riotjs/compiler')>('@riotjs/compiler');
    if (!compiler) return undefined; // skipped

    const { code, map } = compiler.compile(source, { file });
    const mappings = mappingsFromSourceMap(map, code, source);

    return { code, lang: 'js', mappings };
  },
};
```

1. Load the tool with `context.load` so its version matches the app's. Return `undefined` when it is missing: the format is skipped with one warning naming the packages in `requires`.
2. Build `mappings` with `mappingsFromSourceMap` for a version 3 source map, or `mappingsFromVolar` for the mappings of a Volar-based tool.
3. Throw when the tool rejects a file. That file is skipped with a warning.

## Register the language [#register-language]

Pass it with the defaults:

```ts
import {
  collectContext,
  defaultLanguages,
} from '@generaltranslation/paraglide-js/compiler';
import { riotLanguage } from './riot-language.js';

await collectContext({ languages: [...defaultLanguages, riotLanguage] });
```

Files with the language's extensions are now part of the analysis. When several languages match a file, the first in the list is used.

## Cover scripts and script extensions [#scripts]

- **Separate scripts:** return scripts that are modules of their own, such as an Astro page's client scripts, in `scripts`, each as `{ code, lang, mappings }`. They share no names with each other or with the main `code`.
- **Script extensions:** to claim files with a script extension, as Angular components do with `.ts`, add `detect(source, file)` and return `true` only for files in your format.

## Next steps

- /docs/integrations/paraglide/guides/resolving-imports

## Sitemap

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