# 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+)
- Node.js 18+
**Tip:** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/reference/commands/init). This guide covers manual setup.
**Note:** If you use the Pages Router, follow the [Next.js Pages Router Quickstart](/docs/react/nextjs-pages-router-quickstart) instead.
## 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.
```bash
npm i gt-next
npm i -D gt
```
```bash
yarn add gt-next
yarn add --dev gt
```
```bash
bun add gt-next
bun add --dev gt
```
```bash
pnpm add gt-next
pnpm add --save-dev gt
```
### 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`** 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;
}
```
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` (no API key needed) or `npx gt translate` (with credentials), or add empty `{}` files at `public/_gt/[locale].json`.
`withGTConfig` automatically detects a `loadTranslations.[js|ts]` file in your `src/` directory or project root — no additional configuration needed.
**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.
### 5. Add the GTProvider to your layout
The **`GTProvider`** 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 --] */}
{/* [!code ++] */}
{/* [!code --] */}
{children}
{/* [!code ++:3] */}
{children}
);
}
```
### 6. Mark content for translation
Now, wrap any text you want translated with the **``** component. `` stands for "translate":
```tsx title="app/page.tsx"
import { T } from 'gt-next'; // [!code ++]
export default function Home() {
return (
{/* [!code ++] */}
Welcome to my app
This content will be translated automatically.
{/* [!code ++] */}
);
}
```
You can wrap as much or as little JSX as you want inside ``. Everything inside it — text, nested elements, even formatting — gets translated as a unit.
### 7. Add a language switcher
Drop in a **``** 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 (
{/* [!code ++] */}
Welcome to my app
This content will be translated automatically.
);
}
```
`LocaleSelector` 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/signup) or by running:
```bash
npx gt auth
```
**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.
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 (``, ``, `LocaleSelector`, etc.)
- Run `npx gt generate` to create translation file templates, then translate them yourself
### 9. See it working
Start your dev server:
```bash
npm run dev
```
```bash
yarn dev
```
```bash
bun dev
```
```bash
pnpm dev
```
Open [http://localhost:3000](http://localhost:3000) and use the language dropdown to switch languages. You should see your content translated.
**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.
### 10. Translate strings
For plain strings — like `placeholder` attributes, `aria-label` values, or `alt` text — use the **`useGT`** 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 (
);
}
```
Async components cannot use hooks. Import `getGT` from `gt-next/server` instead:
```tsx
import { getGT } from 'gt-next/server';
export default async function Page() {
const gt = await getGT();
return {gt('Hello')}
;
}
```
### 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
```
**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_`.
That's it — your app is now multilingual. 🎉
## Troubleshooting [#troubleshooting]
`gt-next` stores the user's language preference in a cookie called `generaltranslation.locale`. If you previously tested with a different language, this cookie may override your selection. Clear your cookies and try again.
- [Chrome](https://support.google.com/chrome/answer/95647)
- [Firefox](https://support.mozilla.org/en-US/kb/delete-cookies-remove-info-websites-stored)
- [Safari](https://support.apple.com/en-mn/guide/safari/sfri11471/16.0/mac/11.0)
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`.
Ambiguous text can lead to inaccurate translations. For example, "apple" could mean the fruit or the company. Add a `context` prop to help:
```jsx
Apple
```
Both ``, `useGT()`, and `getGT()` support the `context` option.
## Next steps
- /docs/react/guides/translating-jsx
- /docs/react/guides/translating-strings
- /docs/react/guides/managing-locales
- /docs/react/guides/formatting-variables