From a5a531e6f7bd01068f4a66e674df061a34fada38 Mon Sep 17 00:00:00 2001 From: Ernest McCarter Date: Thu, 9 Jul 2026 15:59:22 -0700 Subject: [PATCH] docs(next): add Pages Router quickstart - New tutorials/quickstart-pages-router page: withGTServerSideProps around getServerSideProps, GTProvider wiring in _app.tsx via WithGTServerSideProps, local translation loading, LocaleSelector, env vars, and deployment - Link to it from the App Router quickstart and add it to the sidebar --- docs/en-US/next/index.mdx | 4 + docs/en-US/next/meta.json | 1 + .../tutorials/quickstart-pages-router.mdx | 369 ++++++++++++++++++ 3 files changed, 374 insertions(+) create mode 100644 docs/en-US/next/tutorials/quickstart-pages-router.mdx diff --git a/docs/en-US/next/index.mdx b/docs/en-US/next/index.mdx index 2d4b8683b..4804318f1 100644 --- a/docs/en-US/next/index.mdx +++ b/docs/en-US/next/index.mdx @@ -13,6 +13,10 @@ By the end of this guide, your Next.js app will display content in multiple lang **Want automatic setup?** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/init). This guide covers manual setup. + + **Using the Pages Router?** Follow the [Pages Router quickstart](/docs/next/tutorials/quickstart-pages-router) instead. + + --- ## Step 1: Install the packages diff --git a/docs/en-US/next/meta.json b/docs/en-US/next/meta.json index 0990f2455..8fe696dea 100644 --- a/docs/en-US/next/meta.json +++ b/docs/en-US/next/meta.json @@ -37,6 +37,7 @@ "./api/types", "---Tutorials---", "./tutorials/quickstart", + "./tutorials/quickstart-pages-router", "./tutorials/quickdeploy", "./tutorials/examples/currency-converter", "./tutorials/examples" diff --git a/docs/en-US/next/tutorials/quickstart-pages-router.mdx b/docs/en-US/next/tutorials/quickstart-pages-router.mdx new file mode 100644 index 000000000..acd1ebcb9 --- /dev/null +++ b/docs/en-US/next/tutorials/quickstart-pages-router.mdx @@ -0,0 +1,369 @@ +--- +title: Pages Router Quickstart +description: Add multiple languages to your Next.js Pages Router app in under 10 minutes +--- + +By the end of this guide, your Next.js Pages Router app will display content in multiple languages, with a language switcher your users can interact with. + +In the Pages Router, `gt-next` works through `getServerSideProps`: on each request, the server resolves the user's locale, loads a translations snapshot, and passes both to a `` in `_app.tsx` so the first render is already translated. + +**Prerequisites:** +- A Next.js app using the **Pages Router** +- Node.js 18+ + + + **Using the App Router?** Follow the [Next.js Quickstart](/docs/next) instead — it uses server components and needs no `getServerSideProps` wiring. + + +--- + +## Step 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 + ``` + + + +--- + +## Step 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: + +```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. The config is identical for the App Router and the Pages Router — no router-specific flags are needed. + +--- + +## Step 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/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/ +``` + +--- + +## Step 4: Add a load function for local translations + +Create a **`loadTranslations`** file in your project root (or `src/` directory). This tells `gt-next` how to load the translation files generated by the CLI: + +```ts title="loadTranslations.ts" +export default async function loadTranslations(locale: string) { + try { + const translations = await import(`./public/_gt/${locale}.json`); + return translations.default; + } catch { + return {}; + } +} +``` + +`withGTConfig` automatically detects a `loadTranslations.[js|ts]` file in your project root or `src/` directory — no additional configuration needed. + + + **Why local translations?** Local translations are bundled with your app, so they load instantly with no reliance on external services. See the [Local Translation Storage guide](/docs/next/guides/local-tx) for more details and trade-offs. + + +--- + +## Step 5: Wrap getServerSideProps on your pages + +Wrap each page's `getServerSideProps` with **`withGTServerSideProps`**. On every request, it resolves the user's locale — from the `generaltranslation.locale` cookie if set, otherwise from the `Accept-Language` header — loads a translations snapshot for that locale, and injects both into your page props: + +```tsx title="pages/index.tsx" +import type { GetServerSideProps } from 'next'; +import { withGTServerSideProps } from 'gt-next'; + +export const getServerSideProps: GetServerSideProps = withGTServerSideProps( + async (context) => { + return { + props: { + // your own props + }, + }; + } +); +``` + +If a page doesn't need server-side props of its own, call it with no arguments: + +```tsx title="pages/about.tsx" +import { withGTServerSideProps } from 'gt-next'; + +export const getServerSideProps = withGTServerSideProps(); +``` + +`withGTServerSideProps` adds `locale` and `translations` to your props (plus an internal `enableI18n` flag). If your inner function returns a `redirect` or `notFound`, it passes the result through untouched without loading translations. + +--- + +## Step 6: Add the GTProvider to your app + +The **`GTProvider`** component gives your entire app access to translations. In `_app.tsx`, pull the injected props out of `pageProps` and pass them to the provider. The **`WithGTServerSideProps`** type describes the injected shape: + +```tsx title="pages/_app.tsx" +import type { AppProps } from 'next/app'; +import { GTProvider, WithGTServerSideProps } from 'gt-next'; + +export default function App({ + Component, + pageProps, +}: AppProps) { + const { locale, translations, ...restPageProps } = pageProps; + + return ( + + + + ); +} +``` + +Because the locale and translations arrive with the server response, the first render is already in the user's language — no client-side loading state. + +--- + +## Step 7: Mark content for translation + +Now, wrap any text you want translated with the **``** component. `` stands for "translate": + +```tsx title="pages/index.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 want inside ``. Everything inside it — text, nested elements, even formatting — gets translated as a unit. + +--- + +## Step 8: Add a language switcher + +Drop in a **``** so users can change languages: + +```tsx title="pages/index.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`. When the user picks a language, `gt-next` saves the choice to the `generaltranslation.locale` cookie and reloads the page, so the server re-renders everything in the new locale. + +--- + +## Step 9: 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 +``` + + + 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. + + +--- + +## Step 10: 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. + + + In development, translations happen on-demand — 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. + + +--- + +## Step 11: Translate strings (not just JSX) + +For plain strings — like `placeholder` attributes, `aria-label` values, or `alt` text — use the **`useGT`** hook: + +```tsx title="pages/contact.tsx" +import { useGT } from 'gt-next'; + +export default function ContactPage() { + const gt = useGT(); + + return ( +
+ + +
+ ); +} +``` + +--- + +## Step 12: 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 +``` + + + 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 + + + + Yes — `` requires the `locale` and `translations` props, and they only exist on pages whose `getServerSideProps` is wrapped. For pages that don't fetch their own data, export the no-argument form: + + ```tsx + export const getServerSideProps = withGTServerSideProps(); + ``` + + + No. Resolving the locale requires per-request data (the locale cookie and `Accept-Language` header), which isn't available during static generation. `gt-next` provides no `getStaticProps` helper for the Pages Router. + + + `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`. + + + +--- + +## Next steps + +- [**`` Component Guide**](/docs/next/guides/t) — Learn about variables, plurals, and advanced translation patterns +- [**String Translation Guide**](/docs/next/guides/strings) — Deep dive into `useGT` +- [**Variable Components**](/docs/next/guides/variables) — Handle dynamic content with ``, ``, ``, and `` +- [**Pluralization**](/docs/next/api/components/plural) — Handle plural forms with the `` component +- [**Deploying to Production**](/docs/next/tutorials/quickdeploy) — CI/CD setup, caching, and performance optimization +- [**Shared Strings**](/docs/next/guides/shared-strings) — Translate text in arrays, config objects, and shared data with `msg()`