OpenRouter

AI translation with OpenRouter and Lingo.dev Compiler

What is OpenRouter?

OpenRouter is a platform that provides access to a wide variety of AI models from different providers through a unified API, allowing developers to compare, switch, and route requests easily. It focuses on flexibility, transparency, and giving users more control over which models they use and how they’re billed.

Setting the API Key

OpenRouter requires an API key to authenticate requests from Lingo.dev Compiler. Choose the setup method that best fits your workflow:

Option 1: Environment Variable (Terminal)

Best for quick experiments and testing without modifying any files.

Set the key directly in your terminal session:

export OPENROUTER_API_KEY="your-api-key-here"

This key will only be available until you close your terminal window.

Option 2: Project Configuration (.env)

Best for project-specific configuration and team environments where each project may use different credentials.

Create a .env file in your project root:

touch .env

Add the following line to the file:

OPENROUTER_API_KEY="your-api-key-here"

Lingo.dev Compiler checks for environment files in this priority order:

  1. .env.development (highest priority)
  2. .env.local
  3. .env (lowest priority)

Values in higher-priority files override those in lower-priority files.

Option 3: Global Configuration (User Settings)

Best for individual developers who want to use the same API key across all their projects.

Create a configuration file in your home directory:

touch ~/.lingodotdevrc

Add the following content to the file:

[llm]
openrouterApiKey="your-api-key-here"

This configuration persists across all terminal sessions and projects on your machine.

Configuration Priority

When multiple configuration methods are used, Lingo.dev Compiler checks for API keys in this order:

  1. Environment variables (highest priority)
  2. Project .env files (in their own priority order)
  3. User configuration file ~/.lingodotdevrc (lowest priority)

The first valid API key that's found is used.

Using OpenRouter

To enable OpenRouter, set the models property in the compiler options:

import react from "@vitejs/plugin-react";
import lingoCompiler from "lingo.dev/compiler";
import { type UserConfig } from "vite";

// https://vite.dev/config/
const viteConfig: UserConfig = {
  plugins: [react()],
};

const withLingo = lingoCompiler.vite({
  sourceRoot: "src",
  lingoDir: "lingo",
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de", "ja"],
  rsc: false,
  useDirective: false,
  debug: false,
  models: {
    "*:*": "openrouter:anthropic/claude-3.5-sonnet",
  },
});

export default withLingo(viteConfig);

The property accepts an object where:

  • the keys are pairs of source and target locales, with * representing any locale
  • the values are model identifiers (e.g., openrouter:anthropic/claude-3.5-sonnet)

You can use OpenRouter to translate:

  • between all locales
  • from a specific source locale
  • to a specific target locale
  • between a specific source and target locale

Translating all locales

Use the wildcard pattern *:* to apply the same OpenRouter model for all translation pairs:

const withLingo = lingoCompiler.vite({
  sourceRoot: "src",
  lingoDir: "lingo",
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de", "ja", "pt", "zh"],
  models: {
    // Use Claude 3.5 Sonnet for all translation pairs
    "*:*": "openrouter:anthropic/claude-3.5-sonnet",
  },
});

Translating from a specific source locale

Use a specific source locale with wildcard target to apply a model for all translations from that source:

const withLingo = lingoCompiler.vite({
  sourceRoot: "src",
  lingoDir: "lingo",
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de", "ja", "pt", "zh"],
  models: {
    // Use Claude 3.5 Sonnet for all translations from English
    "en:*": "openrouter:anthropic/claude-3.5-sonnet",
    // Use GPT-4 Turbo for translations from Spanish to any language
    "es:*": "openrouter:openai/gpt-4-turbo",
    // Fallback for other source languages
    "*:*": "openrouter:meta-llama/llama-3.1-70b",
  },
});

Translating to a specific target locale

Use a wildcard source with specific target locale to apply a model for all translations to that target:

const withLingo = lingoCompiler.vite({
  sourceRoot: "src",
  lingoDir: "lingo",
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de", "ja", "pt", "zh"],
  models: {
    // Use specialized model for translations to Japanese
    "*:ja": "openrouter:anthropic/claude-3-opus",
    // Use Gemini Pro for translations to Chinese
    "*:zh": "openrouter:google/gemini-pro-1.5",
    // Use Mistral Large for translations to French
    "*:fr": "openrouter:mistralai/mistral-large",
    // Default for other target languages
    "*:*": "openrouter:openai/gpt-3.5-turbo",
  },
});

Translating between specific locales

Define exact source-target pairs for fine-grained control over which model handles specific language combinations:

const withLingo = lingoCompiler.vite({
  sourceRoot: "src",
  lingoDir: "lingo",
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de", "ja", "pt", "zh"],
  models: {
    // Specific pairs with optimal models
    "en:es": "openrouter:openai/gpt-3.5-turbo", // English to Spanish
    "en:ja": "openrouter:anthropic/claude-3.5-sonnet", // English to Japanese
    "en:zh": "openrouter:google/gemini-pro-1.5", // English to Chinese
    "en:fr": "openrouter:mistralai/mistral-large", // English to French
    "es:en": "openrouter:meta-llama/llama-3.1-8b", // Spanish to English
    "fr:en": "openrouter:cohere/command-r-plus", // French to English
    "de:en": "openrouter:perplexity/llama-3.1-sonar-large", // German to English

    // Fallback for unspecified pairs
    "*:*": "openrouter:openai/gpt-3.5-turbo",
  },
});