@weglot/translate-react

Translate your
React, Next.js or Vite app

No t() wrappers, no JSON files. Add a build plugin and a Weglot API key: the text in your JSX is translated when your app builds, and your team edits translations in Weglot without touching code.

Get your API key

Requires React 19 Next.js 15 / 16.0.4+ (App Router) or Vite Node 20.9+

// how it works

Four steps. Your components stay as they are.

Source and target languages come from your Weglot project, not from your code. The plugin reads the text in your JSX at build time and fetches its translations.

  1. Install the package and add your API key

    Create a Weglot 2.0 project, then copy its API key from the project settings. It starts with pk_. Keep .env out of version control.

    terminal · .env
    $ npm install @weglot/translate-react
    
    # .env
    WEGLOT_API_KEY=pk_your_weglot_api_key
  2. Add the plugin

    Wrap your Next.js config with withWeglot. Point sourceRoot to the folder that holds your pages and components.

    next.config.ts
    import type { NextConfig } from "next";
    import { withWeglot } from "@weglot/translate-react/next";
    
    const nextConfig: NextConfig = {};
    
    export default async function (): Promise<NextConfig> {
      return await withWeglot(nextConfig, { sourceRoot: "./app" });
    }
  3. Add the provider

    Wrap your root layout with WeglotProvider from the Next.js entry point, so that changing language refreshes your server components.

    app/layout.tsx
    import { WeglotProvider } from "@weglot/translate-react/react/next";
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <body>
            <WeglotProvider>{children}</WeglotProvider>
          </body>
        </html>
      );
    }
  4. Build, and ship in every language of your project

    Each build fetches missing translations from Weglot and writes public/translations/<locale>.json. Ignore that folder. Add a language switcher with LocaleSwitcher or useWeglotContext.

    .gitignore
    public/translations/

// compare

Why not a classic i18n library?

i18n libraries ask you to replace every string with a key and keep one file per language. Weglot reads the strings you already wrote. Here is how the options compare.

Based on each project's public documentation (Weglot, next-intl, Paraglide JS, Contentful, Sanity, Strapi), November 2026.
Criteria Weglot
@weglot/translate-react
next-intl / i18next Paraglide JS CMS native localization
Wrap strings in t() or message functions NoText in JSX is detected at build time. Yest("key") for every string. Yesm.key() message functions. Content onlyStrings in your code still need a library.
Translation files per language None to maintainGenerated at build, git-ignored. YesTypically one JSON file per locale. YesOne message file per locale. NoStored in the CMS.
Multilingual routing and SEO (URL per language, hreflang) Not yetLanguage stored in a cookie. Same URLs for all languages, source language indexed. next-intl: yesLocale routing built in. i18next: through your framework setup. YesLocalized URLs built in: locale prefixes, translated paths or domains. Add hreflang tags yourself. Front endA headless CMS stores content per locale. URLs and hreflang come from your front end.
Translations generated for you YesWeglot translates with an LLM during the build. NoBring your own translations or a TMS. With toolinginlang CLI machine translation, or your coding agent. Paid add-onAI translation on paid plans: Contentful AI Actions, Sanity AI Assist, Strapi AI Translations.
Edit translations without a developer YesReview and edit in the Weglot dashboard. NoEdit JSON files, or add a separate TMS. With Finkinlang's web editor, with a GitHub account. YesIn the CMS editor.
Set up by a coding agent in one prompt YesOne install, two config edits. Copyable prompt below. Long taskThe agent rewrites every string into keys and files. Long taskinit runs without prompts for agents, then every string becomes an m.key() message. n/aConfigured in the CMS.

// built for coding agents

Built for AI coding agents

If you build with Claude Code, Cursor or Codex, your agent can add Weglot on its own. There are no strings to rewrite, so the change is small and easy to review.

01 · setup

The agent installs and configures it

One npm install, one plugin, one provider, one line in .gitignore. The agent only asks you for the API key.

02 · docs

Docs that LLMs can read

The documentation has an llms.txt index, and every page has a Markdown version: add .md to its URL.

03 · prompt

A prompt ready to copy

Each step of the prompt matches the getting-started guide, with the real import paths. Copy it below.

Paste in Claude Code

      

// for your team

Edit and review without touching code

Every translation appears in your Weglot project. Product, marketing and translators review and edit the wording there, without opening a pull request.

  • Review the translations Weglot generates for your app.
  • Edit any translation in the Weglot dashboard.
  • Exclude anything from code with translate="no" or data-weglot-skip.

// fit

When to use Weglot, and when not to

The package is in preview. Here is where it fits today.

Use @weglot/translate-react if

  • Your app runs React 19 on Next.js (App Router) or Vite.
  • You don't want to wrap strings in t() or maintain one file per language.
  • Your coding agent writes most of the code, and you want translation to keep up with it.
  • People who don't code need to review and edit translations.
  • Your UI text lives in code, with CMS content you can translate server-side.

Use something else if

  • You need one URL per language and translated pages indexed by search engines today. Use next-intl or Paraglide JS.
  • You want translations as files in your repo, reviewed in pull requests. Use inlang with Paraglide JS or i18next.
  • Your app is on React 18, the Next.js Pages Router, or Next.js 14 or older.
  • Your site is built in a CMS or website builder, not React. Use Weglot's CMS integrations.

FAQ

Does it handle SEO: one URL per language and hreflang?

Not today. The visitor's language is stored in a cookie and every language is served on the same URLs, so search engines index the source language only.

You can translate page titles and descriptions with tDynamicAll in generateMetadata. If you need indexed URLs per language now, use a library with locale routing, such as next-intl or Paraglide JS.

How do I translate dynamic content from a CMS, an API or users?

The plugin only translates text written in your code. For content your code never sees, call tDynamic, tDynamicAll or tDynamicHtml from @weglot/translate-react/dynamic in Next.js server components.

If the API takes longer than 500 ms, or a text is requested for the first time, they return the source text. The translation is ready on a later request. If you cache data yourself, make the cache depend on the visitor's language.

Next.js or Vite: what changes?

Next.js uses withWeglot from @weglot/translate-react/next and WeglotProvider from @weglot/translate-react/react/next. Vite uses weglotPlugin from @weglot/translate-react/vite and WeglotProvider from @weglot/translate-react/react. Webpack uses weglotPlugin from @weglot/translate-react/webpack.

The dynamic content functions only run in Next.js server components.

Does it work with React Server Components?

Yes, with the Next.js App Router. Import WeglotProvider from @weglot/translate-react/react/next so that changing language refreshes your server components. tDynamic, tDynamicAll and tDynamicHtml run server-side, in server components.

What happens when I build?

The plugin finds the text in the JSX under sourceRoot and asks the Weglot API for the translations it lacks. Weglot generates them with an LLM, and the build waits up to translationTimeout (300 seconds by default). It then writes public/translations/<locale>.json.

If translation fails, the build fails and keeps what it received in the local cache: build again to continue. With buildMode: "cache-only", the build makes no network calls.

Where are the translations stored?

In your Weglot project, where you review and edit them. Each build also keeps the translations it received in <sourceRoot>/weglot/cache/<locale>.json. Commit that folder to build without calling the API, or ignore it. public/translations/ is generated and goes in .gitignore.

What gets translated, and how do I exclude something?

Text in JSX, string literals inside JSX expressions, strings read from constants, and attributes such as title, alt, placeholder and aria-label. Code, URLs, class names and strings outside JSX are left alone. Add translate="no" or data-weglot-skip to keep an element in the original language. Declare your own text props with translatableAttributes.

Make your React app multilingual without rewriting it

Install the package, add your API key, build.

terminal
$ npm install @weglot/translate-react
Get your API key