Get Started with i18.dev
Manage your translations and sync them to your project. Works with any i18n library like i18next, next-intl, react-intl, and more.
Prerequisites
This guide assumes you already have a project set up with an i18n library. i18.dev works with any internationalization library:
Add Your Translations
Create your first set of translation key-value pairs. Choose one of three methods:
Manual Create
Add translation keys and values one by one directly in the dashboard.
Import JSON
Upload your existing translation JSON files to import all keys at once.
AI Code Extractor
Paste your code and let AI automatically extract all translatable strings.
Tip: Use the AI Code Extractor to scan your components and automatically identify hardcoded strings. It generates semantic keys and extracts all translatable content in seconds.
Get Your API Key
Once you have translations in your project, copy your project API key from the project settings to sync translations to your codebase.
Set Up Environment Variables
Add your API key and configuration to your .env file:
# i18.dev Configuration
I18DEV_API_KEY=your-project-api-key
I18DEV_BASE_URL=https://i18.dev
I18DEV_MESSAGES_PATH=messagesCreate the Pull Script
Create a new file at scripts/pull-translations.js:
// This script pulls translations from the i18 translation management API
// and updates the message files in the messages directory.
const fs = require('fs');
const path = require('path');
const https = require('https');
// Environment variables
const BASE_URL = process.env.I18DEV_BASE_URL || 'https://i18.dev';
const API_KEY = process.env.I18DEV_API_KEY;
const MESSAGES_PATH = process.env.I18DEV_MESSAGES_PATH || 'messages';
// API parameters
const version = 'latest';
const state = 'all'; // 'confirmed' | 'unconfirmed' | 'all'
function validateParams() {
const params = {
BASE_URL,
API_KEY,
MESSAGES_PATH,
version,
state
};
const missing = Object.entries(params)
.filter(([, value]) => !value)
.map(([key]) => key);
if (missing.length > 0) {
throw new Error(`Missing required parameters: ${missing.join(', ')}`);
}
return params;
}
// Validate all parameters before constructing URL
validateParams();
const API_URL = `${BASE_URL}/api/download-translations?projectId=${API_KEY}&version=${version}&state=${state}`;
const MESSAGES_DIR = path.join(__dirname, '..', MESSAGES_PATH);
async function fetchTranslations() {
return new Promise((resolve, reject) => {
const req = https.get(API_URL, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
console.log('Raw API response:', data);
const translations = JSON.parse(data);
resolve(translations);
} catch (error) {
reject(new Error(`Failed to parse JSON: ${error.message}`));
}
});
});
req.on('error', (error) => {
reject(new Error(`Request failed: ${error.message}`));
});
req.setTimeout(10000, () => {
req.destroy();
reject(new Error('Request timeout'));
});
});
}
function ensureDirectoryExists(dirPath) {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
}
function updateMessageFiles(translations) {
ensureDirectoryExists(MESSAGES_DIR);
Object.keys(translations).forEach(locale => {
const filePath = path.join(MESSAGES_DIR, `${locale}.json`);
const content = translations[locale];
fs.writeFileSync(filePath, JSON.stringify(content, null, 2), 'utf8');
console.log(`✅ Updated ${locale}.json with namespaces: ${Object.keys(content).join(', ')}`);
});
}
async function main() {
try {
console.log('🔄 Fetching translations from API...');
const translations = await fetchTranslations();
console.log('📝 Updating message files...');
updateMessageFiles(translations);
console.log('✨ Translation files updated successfully!');
console.log(`Updated languages: ${Object.keys(translations).join(', ')}`);
} catch (error) {
console.error('❌ Error:', error.message);
process.exit(1);
}
}
if (require.main === module) {
main();
}
module.exports = { fetchTranslations, updateMessageFiles };Add npm Script
Add the pull command to your package.json:
{
"scripts": {
"pull": "node scripts/pull-translations.js"
}
}Run the Script
Pull your translations from i18.dev:
npm run pullyarn pullpnpm pullExpected Output
Generated File Structure
Configuration Options
| Variable | Description | Default |
|---|---|---|
| I18DEV_API_KEY | Your project API key (required) | - |
| I18DEV_BASE_URL | API base URL | https://i18.dev |
| I18DEV_MESSAGES_PATH | Output directory for translation files | messages |