@@ -13,7 +13,10 @@ automatically transforms React components to inject translation calls.
1313- ** Opt-in or automatic** - Configure whether to require ` 'use i18n' ` directive or transform all files
1414- ** Multi-bundler support** - Works with Vite, Webpack and Next.js (both Webpack and Turbopack builds)
1515- ** Translation server** - On-demand translation generation during development
16- - ** AI-powered translations** - Support for multiple LLM providers and Lingo.dev Engine
16+ - ** AI-powered translations** - Support for multiple LLM providers (OpenAI, Anthropic, Google Gemini, Groq, Mistral, OpenRouter, Ollama) and Lingo.dev Engine
17+ - ** Manual overrides** - Override AI translations for specific locales using ` data-lingo-override ` attribute
18+ - ** Custom locale resolvers** - Provide your own locale detection and persistence logic
19+ - ** Automatic pluralization** - Detects and converts messages to ICU MessageFormat
1720
1821## Getting started
1922
@@ -58,7 +61,7 @@ Install the package - `pnpm install @lingo.dev/compiler`
5861 }
5962 ```
6063
61- See ` demo/vite-react-spa ` for the working example
64+ See ` demo/new-compiler- vite-react-spa ` for the working example
6265
6366### Next.js
6467
@@ -99,6 +102,274 @@ See `demo/vite-react-spa` for the working example
99102 }
100103 ```
101104
105+ See ` demo/new-compiler-next16 ` for the working example
106+
107+ ## Configuration Options
108+
109+ ### Core Configuration
110+
111+ | Option | Type | Default | Description |
112+ | --------| ------| ---------| -------------|
113+ | ` sourceRoot ` | ` string ` | ` "src" ` | Root directory of the source code |
114+ | ` lingoDir ` | ` string ` | ` "lingo" ` | Directory for lingo files (` .lingo/ ` ) |
115+ | ` sourceLocale ` | ` LocaleCode ` | ** (required)** | Source locale (e.g., ` "en" ` , ` "en-US" ` ) |
116+ | ` targetLocales ` | ` LocaleCode[] ` | ** (required)** | Target locales to translate to |
117+ | ` useDirective ` | ` boolean ` | ` false ` | Whether to require ` 'use i18n' ` directive |
118+ | ` models ` | ` string \| Record<string, string> ` | ` "lingo.dev" ` | Model configuration (see below) |
119+ | ` prompt ` | ` string ` | ` undefined ` | Custom translation prompt |
120+ | ` buildMode ` | ` "translate" \| "cache-only" ` | ` "translate" ` | Build mode (see below) |
121+
122+ ### Development Configuration
123+
124+ Configure development-specific behavior via the ` dev ` option:
125+
126+ ``` ts
127+ {
128+ dev : {
129+ // Use pseudotranslator (fake translations) instead of real AI
130+ usePseudotranslator : boolean ; // default: false
131+
132+ // Starting port for translation server
133+ translationServerStartPort : number ; // default: 60000
134+
135+ // Custom translation server URL (advanced)
136+ translationServerUrl ?: string ;
137+ }
138+ }
139+ ```
140+
141+ ### Locale Persistence
142+
143+ Configure how locale changes are persisted:
144+
145+ ``` ts
146+ {
147+ localePersistence : {
148+ type : " cookie" ,
149+ config : {
150+ name : string ; // default: "locale"
151+ maxAge : number ; // default: 31536000 (1 year)
152+ }
153+ }
154+ }
155+ ```
156+
157+ ### Pluralization
158+
159+ Configure automatic pluralization detection:
160+
161+ ``` ts
162+ {
163+ pluralization : {
164+ enabled : boolean ; // default: true
165+ model : string ; // default: "groq:llama-3.1-8b-instant"
166+ }
167+ }
168+ ```
169+
170+ ## Using LLMs for Translation
171+
172+ ### Lingo.dev Engine (Recommended)
173+
174+ The simplest way to get started is using Lingo.dev Engine:
175+
176+ ``` ts
177+ {
178+ models : " lingo.dev"
179+ }
180+ ```
181+
182+ Set your API key in ` .env ` :
183+
184+ ``` bash
185+ LINGODOTDEV_API_KEY=your_api_key_here
186+ ```
187+
188+ Get your API key at [ lingo.dev] ( https://lingo.dev )
189+
190+ ### Direct LLM Providers
191+
192+ You can use any supported LLM provider directly. Configure using locale-pair mapping:
193+
194+ ``` ts
195+ {
196+ models : {
197+ // Specific locale pair
198+ " en:es" : " google:gemini-2.0-flash" ,
199+
200+ // Wildcard patterns
201+ " *:de" : " groq:llama3-8b-8192" , // All translations to German
202+ " en:*" : " openai:gpt-4o" , // All translations from English
203+ " *:*" : " anthropic:claude-3-5-sonnet" // Fallback for all other pairs
204+ }
205+ }
206+ ```
207+
208+ ** Supported Providers:**
209+
210+ | Provider | Model String Format | Environment Variable | Get API Key |
211+ | ----------| ---------------------| ---------------------| -------------|
212+ | ** OpenAI** | ` openai:gpt-4o ` | ` OPENAI_API_KEY ` | [ platform.openai.com] ( https://platform.openai.com/account/api-keys ) |
213+ | ** Anthropic** | ` anthropic:claude-3-5-sonnet ` | ` ANTHROPIC_API_KEY ` | [ console.anthropic.com] ( https://console.anthropic.com/get-api-key ) |
214+ | ** Google** | ` google:gemini-2.0-flash ` | ` GOOGLE_API_KEY ` | [ ai.google.dev] ( https://ai.google.dev/ ) |
215+ | ** Groq** | ` groq:llama3-8b-8192 ` | ` GROQ_API_KEY ` | [ groq.com] ( https://groq.com ) |
216+ | ** Mistral** | ` mistral:mistral-large ` | ` MISTRAL_API_KEY ` | [ console.mistral.ai] ( https://console.mistral.ai ) |
217+ | ** OpenRouter** | ` openrouter:anthropic/claude-3.5-sonnet ` | ` OPENROUTER_API_KEY ` | [ openrouter.ai] ( https://openrouter.ai ) |
218+ | ** Ollama** | ` ollama:llama2 ` | * (none required)* | [ ollama.com/download] ( https://ollama.com/download ) |
219+
220+ ** Example with multiple providers:**
221+
222+ ``` ts
223+ {
224+ sourceLocale : " en" ,
225+ targetLocales : [" es" , " de" , " fr" , " ja" ],
226+ models : {
227+ " en:es" : " groq:llama3-8b-8192" , // Fast & cheap for Spanish
228+ " en:de" : " google:gemini-2.0-flash" , // Good for German
229+ " *:*" : " openai:gpt-4o" // High quality for everything else
230+ }
231+ }
232+ ```
233+
234+ ### Custom Translation Prompts
235+
236+ Customize the translation prompt using placeholders:
237+
238+ ``` ts
239+ {
240+ models : " lingo.dev" ,
241+ prompt : " Translate from {SOURCE_LOCALE} to {TARGET_LOCALE}. Use a formal tone and preserve all technical terms."
242+ }
243+ ```
244+
245+ ## Manual Translation Overrides
246+
247+ Override AI-generated translations for specific text using the ` data-lingo-override ` attribute:
248+
249+ ``` tsx
250+ export function Welcome() {
251+ return (
252+ <div >
253+ { /* Override translations for brand name */ }
254+ <h1 data-lingo-override = { { de: " Lingo.dev" , fr: " Lingo.dev" , es: " Lingo.dev" }} >
255+ Lingo.dev
256+ </h1 >
257+
258+ { /* Override only specific locales */ }
259+ <p data-lingo-override = { { de: " Professionelle Übersetzung" }} >
260+ Professional translation
261+ </p >
262+
263+ { /* Works with rich text and interpolations */ }
264+ <p data-lingo-override = { {
265+ de: " Willkommen <strong0>{name}</strong0>" ,
266+ fr: " Bienvenue <strong0>{name}</strong0>"
267+ }} >
268+ Welcome <strong >{ name } </strong >
269+ </p >
270+ </div >
271+ );
272+ }
273+ ```
274+
275+ The ` data-lingo-override ` attribute:
276+ - Accepts an object with locale codes as keys
277+ - Supports partial overrides (only specify locales you want to override)
278+ - Is automatically removed from the final output
279+ - Works with locale region codes (e.g., ` en-US ` , ` en-GB ` )
280+ - Supports rich text with component placeholders (e.g., ` <strong0> ` )
281+
282+ ** Use cases:**
283+ - Brand names that shouldn't be translated
284+ - Technical terms requiring specific translations
285+ - Legal text requiring certified translations
286+ - Marketing copy that needs human review
287+
288+ ## Build Modes
289+
290+ Control how translations are handled at build time:
291+
292+ ### ` translate ` (default)
293+
294+ Generate missing translations at build time using configured LLM:
295+
296+ ``` ts
297+ {
298+ buildMode : " translate"
299+ }
300+ ```
301+
302+ - Generates translations for any missing entries
303+ - Fails build if translation fails
304+ - Best for: Development and CI pipelines with API keys
305+
306+ ### ` cache-only `
307+
308+ Only use existing cached translations:
309+
310+ ``` ts
311+ {
312+ buildMode : " cache-only"
313+ }
314+ ```
315+
316+ - No API calls made during build
317+ - Fails build if translations are missing
318+ - Best for: Production builds without API keys
319+ - Requires translations to be pre-generated (during dev or in CI)
320+
321+ ** Environment Variable Override:**
322+
323+ ``` bash
324+ LINGO_BUILD_MODE=cache-only npm run build
325+ ```
326+
327+ ** Recommended Workflow:**
328+
329+ 1 . ** Development** : Use ` translate ` mode with ` usePseudotranslator: true `
330+ 2 . ** CI** : Generate real translations with ` buildMode: "translate" ` and real API keys
331+ 3 . ** Production Build** : Use ` buildMode: "cache-only" ` (no API keys needed)
332+
333+ ## Custom Locale Resolvers
334+
335+ Customize how locales are detected and persisted by providing custom resolver files:
336+
337+ ### Custom Server Locale Resolver
338+
339+ Create ` .lingo/locale-resolver.server.ts ` (Next.js):
340+
341+ ``` ts
342+ // Custom server-side locale detection
343+ export async function getServerLocale(): Promise <string > {
344+ // Your custom logic - e.g., from database, headers, etc.
345+ const { headers } = await import (' next/headers' );
346+ const headersList = await headers ();
347+ const acceptLanguage = headersList .get (' accept-language' );
348+
349+ // Parse and return locale
350+ return acceptLanguage ?.split (' ,' )[0 ]?.split (' -' )[0 ] || ' en' ;
351+ }
352+ ```
353+
354+ ### Custom Client Locale Resolver
355+
356+ Create ` .lingo/locale-resolver.client.ts ` :
357+
358+ ``` ts
359+ // Custom client-side locale detection and persistence
360+ export function getClientLocale(): string {
361+ // Your custom logic - e.g., from localStorage, URL params, etc.
362+ return localStorage .getItem (' user-locale' ) || ' en' ;
363+ }
364+
365+ export function persistLocale(locale : string ): void {
366+ localStorage .setItem (' user-locale' , locale );
367+ // Optionally update URL, etc.
368+ }
369+ ```
370+
371+ If these files don't exist, the compiler uses the default cookie-based implementation.
372+
102373## Development
103374
104375` pnpm install ` from project root
0 commit comments