# General Translation React SDKs (gt-react, gt-next): Next.js App Router Quickstart URL: https://generaltranslation.com/en-GB/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 --- # Next.js App Router Quickstart 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 internationalisation at build time. Wrap your existing Next.js config with it: ```ts title="next.config.ts" import { withGTConfig } from 'gt-next/config'; const nextConfig = {}; export default withGTConfig(nextConfig); ``` 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; } ``` `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: ```tsx title="app/layout.tsx" import { GTProvider, useLocale } from 'gt-next'; export default function RootLayout({ children }: { children: React.ReactNode }) { const locale = useLocale(); return ( {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'; export default function Home() { return (

Welcome to my app

This content will be translated automatically.

); } ``` You can wrap as much or as little JSX as you like 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, LocaleSelector } from 'gt-next'; export default function Home() { return (

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