Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions docs/en-US/next/guides/dynamic-content.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,61 @@ async function ProductReview({ review }) {
}
```

## API route usage

[`tx`](/docs/next/api/strings/tx) works in Next.js API route handlers, not just server components:

```tsx
// app/api/translate/route.ts
import { tx } from 'gt-next/server';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
const { text, locale } = await request.json();
const translated = await tx(text, { locale });
return NextResponse.json({ translated });
}
```

This is useful when you need to expose translation as an API endpoint — for example, to serve client components or external services.

## Client-side translation pattern

Since [`tx`](/docs/next/api/strings/tx) is server-only, client components can translate dynamic content by calling an API route as a proxy:

```tsx
'use client';

async function translateText(text: string) {
const res = await fetch('/api/translate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text, locale: 'fr' }),
});
const { translated } = await res.json();
return translated;
}
```

This pairs with the [API route above](#api-route-usage) to give client components access to dynamic translation.

## Translating multiple items

Use `Promise.all` to translate arrays of content in parallel:

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

const translatedPosts = await Promise.all(
posts.map(async (post) => ({
...post,
title: await tx(post.title),
}))
);
```

This is useful for translating lists of database records, API responses, or any collection of dynamic strings.

## Common issues

### Avoid overuse
Expand Down
40 changes: 40 additions & 0 deletions docs/en-US/react/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ export default async function loadTranslations(locale: string) {

This function loads JSON translation files from your `public/_gt/` directory. The CLI generates these files when you run `npx gt translate`.

<Callout type="warn">
**Using Create React App?** CRA's webpack config blocks dynamic `import()` from outside `src/`. Use `fetch()` instead:

```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
try {
const response = await fetch(`${process.env.PUBLIC_URL}/_gt/${locale}.json`);
if (!response.ok) throw new Error('Not found');
return await response.json();
} catch (error) {
console.warn(`No translations found for ${locale}`);
return {};
}
}
```
</Callout>

---

## Step 4: Add the GTProvider to your app
Expand All @@ -110,6 +127,29 @@ export default function App() {

`GTProvider` takes your config and translation loader as props. It manages locale state and makes translations available to all child components.

<Callout type="warn">
**Using Create React App?** CRA restricts imports to files inside `src/`, so `import gtConfig from '../gt.config.json'` will fail. Either copy `gt.config.json` into `src/`, or inline the config directly:

```tsx title="src/App.tsx"
import { GTProvider } from 'gt-react';
import loadTranslations from './loadTranslations';

export default function App() {
return (
<GTProvider
config={{
defaultLocale: 'en',
locales: ['es', 'fr', 'ja'],
}}
loadTranslations={loadTranslations}
>
{/* Your app content */}
</GTProvider>
);
}
```
</Callout>

---

## Step 5: Mark content for translation
Expand Down
Loading