i18.dev
HomePricingquick setupinstall cli
Quick Start Guide

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:

i18nextreact-i18nextnext-intlreact-intlvue-i18nangular-i18nsvelte-i18nformatjs
1

Create a New Project

Sign up or log in to i18.dev and create a new project. Give it a name and select your target languages.

2

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.

Recommended

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.

3

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.

4

Set Up Environment Variables

Add your API key and configuration to your .env file:

.env
# i18.dev Configuration
I18DEV_API_KEY=your-project-api-key
I18DEV_BASE_URL=https://i18.dev
I18DEV_MESSAGES_PATH=messages
5

Create the Pull Script

Create a new file at scripts/pull-translations.js:

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 };
6

Add npm Script

Add the pull command to your package.json:

package.json
{
  "scripts": {
    "pull": "node scripts/pull-translations.js"
  }
}
7

Run the Script

Pull your translations from i18.dev:

npm
npm run pull
yarn
yarn pull
pnpm
pnpm pull

Expected Output

🔄 Fetching translations from API...
Raw API response: { ... }
📝 Updating message files...
✅ Updated en.json with namespaces: common, auth, dashboard
✅ Updated es.json with namespaces: common, auth, dashboard
✅ Updated fr.json with namespaces: common, auth, dashboard
✨ Translation files updated successfully!
Updated languages: en, es, fr

Generated File Structure

your-project/
├── messages/
│ ├── en.json
│ ├── es.json
│ ├── fr.json
│ └── ...
├── scripts/
│ └── pull-translations.js
├── .env
└── package.json

Configuration Options

VariableDescriptionDefault
I18DEV_API_KEYYour project API key (required)-
I18DEV_BASE_URLAPI base URLhttps://i18.dev
I18DEV_MESSAGES_PATHOutput directory for translation filesmessages

Ready to Get Started?

Create your first project and start managing translations effortlessly.