# General Translation React SDKs (gt-react, gt-next, gt-react-native): Next.js App Router Quickstart
URL: https://generaltranslation.com/en-US/docs/react/nextjs-quickstart.mdx
---

title: Next.js App Router Quickstart
description: Add multiple languages to a Next.js App Router app with General Translation in under 10 minutes.
related:
  links:
    - /docs/react/guides/translating-jsx
    - /docs/react/guides/translating-strings
    - /docs/react/guides/managing-locales
    - /docs/react/guides/formatting-variables

---

By the end of this guide, your Next.js app will display content in multiple languages, with a language switcher your users can interact with.

**Prerequisites:**
- A Next.js app using the **App Router** (Next.js 13.0.0 or later, excluding 15.2.1 and 15.2.2)
- Node.js 18+

<Callout type='info'>
  **Tip:** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/quickstart). This guide covers manual setup.
</Callout>

<Callout type='info'>
  **Note:** If you use the Pages Router, follow the [Next.js Pages Router Quickstart](/docs/react/nextjs-pages-router-quickstart) instead.
</Callout>


## Quickstart [#quickstart]

### 1. Install the packages

`gt-next` is the library that powers translations in your app. `gt` is the CLI tool that prepares translations for production.

<Tabs items={['npm', 'yarn', 'bun', 'pnpm']}>
  <Tab value="npm">
  ```bash
  npm i gt-next
  npm i -D gt
  ```
  </Tab>
  <Tab value="yarn">
  ```bash
  yarn add gt-next
  yarn add --dev gt
  ```
  </Tab>
  <Tab value="bun">
  ```bash
  bun add gt-next
  bun add --dev gt
  ```
  </Tab>
  <Tab value="pnpm">
  ```bash
  pnpm add gt-next
  pnpm add --save-dev gt
  ```
  </Tab>
</Tabs>


### 2. Configure your Next.js config

`gt-next` uses a Next.js plugin called **`withGTConfig`** to set up internationalization at build time. Wrap your existing Next.js config with it. In this snippet and the ones below, green lines are added and red lines are removed; keep any options your config already has:

```ts title="next.config.ts"
import { withGTConfig } from 'gt-next/config'; // [!code ++]

const nextConfig = {};

export default nextConfig; // [!code --]
export default withGTConfig(nextConfig); // [!code ++]
```

This plugin reads your translation settings and wires everything together behind the scenes. No other changes to your Next.js config are needed.


### 3. Create a translation config file

Create a **`gt.config.json`** file in your project root. This tells the library which languages you support:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "fr", "ja"],
  "files": {
    "gt": {
      "output": "public/_gt/[locale].json"
    }
  }
}
```

- **`defaultLocale`** — the language your app is written in (your source language).
- **`locales`** — the languages you want to translate into. Pick any from the [supported locales list](/docs/platform/dashboard/reference/supported-locales).
- **`files.gt.output`** — where the CLI saves translation files. `[locale]` is replaced with each language code (e.g., `public/_gt/es.json`).

Add `public/_gt/` to your **`.gitignore`** — these files are generated, not hand-written:

```txt title=".gitignore"
public/_gt/
```


### 4. Add a load function for local translations

Create a **[`loadTranslations`](/docs/react/reference/functions/load-translations)** file in your `src/` directory (or project root). This tells `gt-next` how to load the translation files generated by the CLI:

```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
  const translations = await import(`../public/_gt/${locale}.json`);
  return translations.default;
}
```

<Callout type="warn">
  **Warning:** These translation files do not exist until you create them, so the first `npm run dev` fails to compile and the page returns HTTP 500. Run [`npx gt generate`](/docs/cli/reference/commands/generate) (no API key needed) or [`npx gt translate`](/docs/cli/reference/commands/translate) (with credentials), or add empty `{}` files at `public/_gt/[locale].json`.
</Callout>

`withGTConfig` automatically detects a `loadTranslations.[js|ts]` file in your `src/` directory or project root — no additional configuration needed.

<Callout type='info'>
  **Note:** Local translations are bundled with your app, so they load instantly with no reliance on external services. See [Storing translations](/docs/react/guides/storing-translations) for details and trade-offs.
</Callout>


### 5. Add the GTProvider to your layout

The **[`GTProvider`](/docs/react/reference/components/gt-provider)** component gives your entire app access to translations. It must wrap your app at the root layout level. Keep the rest of your existing layout (fonts, metadata, styles) as it is:

```tsx title="app/layout.tsx"
import { GTProvider, useLocale } from 'gt-next'; // [!code ++]

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const locale = useLocale(); // [!code ++]
  return (
    {/* [!code --] */}
    <html lang="en">
    {/* [!code ++] */}
    <html lang={locale}>
      <body>
        {/* [!code --] */}
        {children}
        {/* [!code ++:3] */}
        <GTProvider>
          {children}
        </GTProvider>
      </body>
    </html>
  );
}
```

### 6. Mark content for translation

Now, wrap any text you want translated with the **[`<T>`](/docs/react/reference/components/t)** component. [`<T>`](/docs/react/reference/components/t) stands for "translate":

```tsx title="app/page.tsx"
import { T } from 'gt-next'; // [!code ++]

export default function Home() {
  return (
    <main>
      {/* [!code ++] */}
      <T>
        <h1>Welcome to my app</h1>
        <p>This content will be translated automatically.</p>
      {/* [!code ++] */}
      </T>
    </main>
  );
}
```

You can wrap as much or as little JSX as you want inside [`<T>`](/docs/react/reference/components/t). Everything inside it — text, nested elements, even formatting — gets translated as a unit.


### 7. Add a language switcher

Drop in a **[`<LocaleSelector>`](/docs/react/reference/components/locale-selector)** so users can change languages:

```tsx title="app/page.tsx"
import { T } from 'gt-next'; // [!code --]
import { T, LocaleSelector } from 'gt-next'; // [!code ++]

export default function Home() {
  return (
    <main>
      {/* [!code ++] */}
      <LocaleSelector />
      <T>
        <h1>Welcome to my app</h1>
        <p>This content will be translated automatically.</p>
      </T>
    </main>
  );
}
```

[`LocaleSelector`](/docs/react/reference/components/locale-selector) renders a dropdown populated with the languages from your `gt.config.json`.


### 8. Set up environment variables (optional)

To see translations in development, you need API keys from General Translation. These enable **on-demand translation** — your app translates content in real time as you develop.

Create a **`.env.local`** file:

```bash title=".env.local"
GT_API_KEY="your-api-key"
GT_PROJECT_ID="your-project-id"
```

Get your free keys at [dash.generaltranslation.com](https://dash.generaltranslation.com/en-US/signin) or by running:

```bash
npx gt auth
```

<Callout type="warn">
  **Warning:** For development, use a key starting with `gtx-dev-`. Production keys (`gtx-api-`) are for CI/CD only.

  Never expose `GT_API_KEY` to the browser or commit it to source control.
</Callout>

<Accordions>
  <Accordion title="Can I use gt-next without API keys?">
    Yes. Without API keys, `gt-next` works as a standard i18n library. You won't get on-demand translation in development, but you can still:
    - Provide your own translation files manually
    - Use all components ([`<T>`](/docs/react/reference/components/t), [`<Var>`](/docs/react/reference/components/var), [`LocaleSelector`](/docs/react/reference/components/locale-selector), etc.)
    - Run [`npx gt generate`](/docs/cli/reference/commands/generate) to create translation file templates, then translate them yourself
  </Accordion>
</Accordions>


### 9. See it working

Start your dev server:

<Tabs items={['npm', 'yarn', 'bun', 'pnpm']}>
  <Tab value="npm">
  ```bash
  npm run dev
  ```
  </Tab>
  <Tab value="yarn">
  ```bash
  yarn dev
  ```
  </Tab>
  <Tab value="bun">
  ```bash
  bun dev
  ```
  </Tab>
  <Tab value="pnpm">
  ```bash
  pnpm dev
  ```
  </Tab>
</Tabs>

Open [http://localhost:3000](http://localhost:3000) and use the language dropdown to switch languages. You should see your content translated.

<Callout type="info">
  **Note:** In development, translations happen on-demand, so you may see a brief loading state the first time you switch to a new language. In production, translations are pre-generated and load instantly.
</Callout>


### 10. Translate strings

For plain strings — like `placeholder` attributes, `aria-label` values, or `alt` text — use the **[`useGT`](/docs/react/reference/hooks/use-gt)** hook. It works in synchronous server and client components:

```tsx title="app/contact/page.tsx"
import { useGT } from 'gt-next';

export default function ContactPage() {
  const gt = useGT();

  return (
    <form>
      <input
        placeholder={gt('Enter your email')}
        aria-label={gt('Email input field')}
      />
      <button type="submit">{gt('Send')}</button>
    </form>
  );
}
```

<Accordions>
  <Accordion title="Using an async component?">
    Async components cannot use hooks. Import [`getGT`](/docs/react/nextjs/reference/functions/get-gt) from `gt-next/server` instead:

    ```tsx
    import { getGT } from 'gt-next/server';

    export default async function Page() {
      const gt = await getGT();
      return <p>{gt('Hello')}</p>;
    }
    ```
  </Accordion>
</Accordions>


### 11. Deploy to production

In production, translations are pre-generated at build time (no real-time API calls). Add the translate command to your build script:

```json title="package.json"
{
  "scripts": {
    "build": "npx gt translate && next build"
  }
}
```

Set your **production** environment variables in your hosting provider (Vercel, Netlify, etc.):

```bash
GT_PROJECT_ID=your-project-id
GT_API_KEY=gtx-api-your-production-key
```

<Callout type="warn">
  **Warning:** Production keys start with `gtx-api-` (not `gtx-dev-`). Get one from [dash.generaltranslation.com](https://dash.generaltranslation.com). Never prefix it with `NEXT_PUBLIC_`.
</Callout>

That's it — your app is now multilingual. 🎉


## Troubleshooting [#troubleshooting]

<Accordions>
  <Accordion title="The language isn't changing when I use the dropdown">
    Confirm that browser cookies are enabled and the selector renders under [`<GTProvider>`](/docs/react/reference/components/gt-provider). If locale routing is enabled, also confirm that the middleware matcher and [`pathRegex`](/docs/react/nextjs/config#path-regex) include the current route.
  </Accordion>
  <Accordion title="Translations are slow in development">
    This is expected. In development, translations happen on-demand (your content is translated in real time via the API). This delay **does not exist in production** — all translations are pre-generated by [`npx gt translate`](/docs/cli/reference/commands/translate).
  </Accordion>
  <Accordion title="Some translations are inaccurate">
    Ambiguous text can lead to inaccurate translations. For example, "apple" could mean the fruit or the company. Add a `$context` prop to help:

    ```jsx
    <T $context="the technology company">Apple</T>
    ```

    [`<T>`](/docs/react/reference/components/t), [`useGT()`](/docs/react/reference/hooks/use-gt), and [`getGT()`](/docs/react/nextjs/reference/functions/get-gt) all support `$context`.
  </Accordion>
</Accordions>

## Next steps

- /docs/react/guides/translating-jsx
- /docs/react/guides/translating-strings
- /docs/react/guides/managing-locales
- /docs/react/guides/formatting-variables

