FAQ

Common questions and answers about Lingo.dev Compiler.

Can I translate string literals?

Lingo.dev Compiler follows the convention that everything in JSX is localizable. String literals outside of JSX components are not localized by design.

Current behavior:

// This will NOT be translated
const message = "Hello world";
const errorText = "Something went wrong";

// This WILL be translated
function Component() {
  return <h1>Hello world</h1>;
}

Making literals localizable:

You can make string literals localizable by wrapping them in JSX fragments:

// Before: Not localizable
const message = "Hello world";

// After: Localizable using fragments
const message = <>Hello world</>;

// Usage in your component
function Component() {
  return <div>{message}</div>;
}

Alternative approach:

// For dynamic messages
function getLocalizedMessage() {
  return <>Something went wrong</>;
}

// For conditional text
const statusText = isError ? <>Error occurred</> : <>Success</>;

This convention ensures consistent localization behavior while maintaining clear boundaries between localizable and non-localizable content.

We're exploring ways to extend this behavior to support more use cases in the future. Join our Discord to discuss specific patterns you'd like to see supported.

Why aren't my collection-based components being translated?

The compiler currently has a limitation with components based on Adobe React-Aria/React-Stately that expect collections as children. Direct text content in collection items is not automatically localized.

This affects components like Select, Listbox, Menu, and similar collection-based components from libraries such as HeroUI, NextUI, and other React-Aria implementations.

Current behavior:

import { Select, SelectItem } from "@heroui/react";

export default function SelectExample() {
  return (
    <Select label="Select an animal">
      {/* This text will NOT be translated */}
      <SelectItem key="cat" textValue="Cat">
        Cat
      </SelectItem>
      <SelectItem key="dog" textValue="Dog">
        Dog
      </SelectItem>
    </Select>
  );
}

Workaround:

Wrap the text content in JSX fragments to make it localizable:

import { Select, SelectItem } from "@heroui/react";

export default function SelectWithWorkaround() {
  return (
    <Select label="Select an animal">
      {/* This text WILL be translated */}
      <SelectItem key="cat" textValue="Cat">
        <>Cat</>
      </SelectItem>
      <SelectItem key="dog" textValue="Dog">
        <>Dog</>
      </SelectItem>
    </Select>
  );
}

This limitation affects any component that uses React-Aria's collection pattern where text content is passed directly as children to collection items. We're working on improving compiler support for these cases.

Which frameworks are supported?

Lingo.dev Compiler currently supports these React frameworks:

  • Next.js (App Router only)
  • React Router v6+
  • Remix (latest version)
  • Vite + React

We welcome contributors interested in implementing compiler support for other platforms. Join our Discord to discuss implementation strategies.

Can I add more languages?

Yes! You can extend language support by configuring custom models directly in your compiler configuration:

const compilerConfig = {
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de", "pt", "it"],
  models: {
    "*:pt": "qwen/qwen3-32b",
    "en:it": "meta-llama/llama-4-maverick-17b-128e-instruct",
    "*:*": "qwen/qwen3-32b",
  },
};

lingoCompiler.next(compilerConfig)(nextConfig);

See advanced configuration for details.

Can I use custom prompts?

Yes! You can customize translation prompts directly in your compiler configuration:

const compilerConfig = {
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de"],
  prompt:
    "You are a professional translator specializing in technical documentation. Translate from {SOURCE_LOCALE} to {TARGET_LOCALE} while maintaining technical accuracy.",
};

For custom glossaries, include terminology definitions in your prompt. Reference our default prompt for best practices.

Can I use more LLM providers?

Currently, Lingo.dev Compiler integrates with Lingo.dev Engine and multiple other LLM providers.

We'd love to support more LLM providers soon - talk to us or send us a pull request!

Do I need GROQ API key in CI/CD?

Usually no. If you build your app locally all translations will be stored in lingo/ directory. Your CI/CD build will not need to call LLM to translate any strings.

Alternatively you can add GROQ_API_KEY variable to your CI/CD and do all the translations there at build, but we do not recomment this approach to keep more control over final translations.

Can I edit translations?

Yes! You can edit the lingo/dictionary.js file manually. It exports an object with translations for all files and entries. You can edit the text for each locale in content prop. Your edits will be preserved until the source text in React components is updated.

Not a fan of editing JavaScript objects? We are releasing editor to improve the editing experience soon. Let us know if you are interested!

How can I retranslate my whole app, specific file or language?

To retranslate your whole app delete the dictionary.js file from lingo/ directory.

To retranslate specific files only, you can delete their key (filename) from dictionary.js.

If you want to retranslate specific locale, you need to delete all records for that locale.

Why do I need to build the app locally?

Local builds normalize your lingo/ translation files by:

  • Removing unused translation keys
  • Updating content fingerprints
  • Ensuring consistent file formatting
  • Optimizing for production deployment

Always run npm run build before committing changes to maintain clean translation files.

There are missing translations!

If translations are missing:

  1. Build locally to normalize your lingo/ files:

    npm run build
    
  2. Check your API key is properly set:

    # Verify your .env file contains
    GROQ_API_KEY=gsk_...
    
  3. Commit the updated files:

    git add lingo/
    git commit -m "Update translations"
    
  4. Restart your development server after changes.

Can I setup a custom glossary?

Yes! Use custom prompts to define terminology and glossaries directly in your compiler configuration:

const compilerConfig = {
  sourceLocale: "en",
  targetLocales: ["es", "fr", "de"],
  prompt:
    "You are a professional translator. Use these terms consistently: 'Dashboard' should be 'Tableau de bord' in French, 'Settings' should be 'Configuración' in Spanish. Translate from {SOURCE_LOCALE} to {TARGET_LOCALE}.",
};

How does the compiler handle pluralization?

The compiler automatically handles basic pluralization patterns, but for complex plural rules, you may need to structure your JSX accordingly:

// The compiler will handle this appropriately
<p>{count === 1 ? <>1 item</> : <>{count} items</>}</p>

What about performance in production?

Lingo.dev Compiler is optimized for production:

  • Zero runtime cost - translations are pre-compiled
  • Bundle splitting - only active locale is loaded
  • Tree shaking - unused translations are removed
  • CDN-friendly - static translation files cache efficiently

Can I use this with TypeScript?

Yes! The compiler works seamlessly with TypeScript projects. All provided React components are fully typed:

import { LocaleSwitcher } from "lingo.dev/react/client";

// Full TypeScript support
const locales: string[] = ["en", "es", "fr"];
<LocaleSwitcher locales={locales} />;

How do I report bugs or request features?

Next Steps