Astro
The translate-projects-astro package translates the i18n JSON files of your Astro site. You write the texts in one language and get the others in the folder structure that i18next expects.
Requirements
- Node.js 18 or higher.
- A Translate Projects project and an API token. See Getting started.
1. Install the package
npm i -D translate-projects-astro
2. Write your texts
Put the texts of the base language in public/locales/<base language>/. You can have several .json files, also in subfolders, with nested keys. The package only reads and writes JSON, so it does not depend on the Astro version:
{
"title": "Bienvenido",
"menu": { "home": "Inicio" }
}
3. Configure the translation
Create translate.mjs. If you don't pass apiKey, the TRANSLATE_PROJECTS_API_KEY environment variable is used:
import { translateProject } from 'translate-projects-astro';
await translateProject({
sourceLang: 'es', // Base language: the default language of the project
targetLangs: ['en', 'pt-BR', 'fr'], // Languages to generate
});
| Option | Default | Description |
|---|---|---|
sourceLang | — | Language of the source files. |
targetLangs | — | Languages to generate; the base language is skipped. |
apiKey | process.env.TRANSLATE_PROJECTS_API_KEY | Project API token. |
outputDir | ./public/locales | Folder with one subfolder per language. |
Add the script to package.json:
{
"scripts": {
"translate": "node translate.mjs"
}
}
4. Translate
export TRANSLATE_PROJECTS_API_KEY=tu_token
npm run translate
Files it generates
public/locales/
├── es/translation.json ← source, never modified
├── en/translation.json
├── pt-BR/translation.json
└── fr/translation.json
Each file keeps the structure of the original: nested objects, arrays and keys with dots such as "v1.0". Up to 3 languages are translated in parallel.
5. Use the translations in Astro
You can read the files with i18next or directly with import.meta.glob:
---
export function getStaticPaths() {
const files = import.meta.glob('/public/locales/*/translation.json');
return Object.keys(files).map((file) => ({
params: { lang: file.split('/')[3] },
}));
}
const files = import.meta.glob('/public/locales/*/translation.json', {
eager: true,
import: 'default',
});
const { lang } = Astro.params;
const t = files[`/public/locales/${lang}/translation.json`];
---
<h1>{t.title}</h1>
Cache and force
A second run without changes makes a single request and translates nothing. This package has no --force: to translate everything again, delete ~/.config/translate-projects-core/cache.json and run it again. More details in Cache and errors.
Common errors
translateProject returns true if everything went well. If it fails, it shows the error, returns false and leaves the exit code at 1, without closing your process.
- Invalid token, 4xx/5xx errors or API down: the run fails with the API message. Existing files are never overwritten with empty or partial data; the languages that worked are written.
- Missing AI key (
MISSING_API_KEY): the project has no AI configured. Untranslated texts keep the source text, a warning is shown (the exit code is still 0) and they are requested again in the next run. Source folder not found: checksourceLangandoutputDir, and run the command from the root of the site.Invalid JSON file: a source file is not valid JSON; fix it. Nothing is written for it.
🚀 Automate your translations for free
Translate Projects is free. You create your project, connect your AI provider's key, and only pay them what you spend.
- No plans or credit card required: All features are available from day one.
- Use your own AI: Claude, OpenAI, DeepSeek, or Gemini. Your key is stored encrypted.
- Shared translation network: If a text has already been translated, you receive it instantly without spending your key.
- Admin panel: Review and edit all your translations from one place.
We're here to help
If you have any questions, need help, or want to contribute, don't hesitate to contact me. I'm available to support you with whatever you need.
- Website: neiderruiz.com
- GitHub: @neiderruiz
- Twitter: @neiderruiz
- YouTube: Neider Ruiz
Support the Project
If this project has been helpful to you, I invite you to buy me a coffee. Your support helps me keep improving and creating valuable content. Thanks for being here! ☕