From a4a6a14a7a82b016d592c37b7d81179605ab709e Mon Sep 17 00:00:00 2001
From: moss-bryophyta <261561981+moss-bryophyta@users.noreply.github.com>
Date: Thu, 26 Mar 2026 11:46:08 -0700
Subject: [PATCH] docs(gt-next): add API route and client-side patterns to
dynamic content guide
---
docs/en-US/next/guides/dynamic-content.mdx | 55 ++++++++++++++++++++++
docs/en-US/react/index.mdx | 40 ++++++++++++++++
2 files changed, 95 insertions(+)
diff --git a/docs/en-US/next/guides/dynamic-content.mdx b/docs/en-US/next/guides/dynamic-content.mdx
index 4059a10..5cb3d87 100644
--- a/docs/en-US/next/guides/dynamic-content.mdx
+++ b/docs/en-US/next/guides/dynamic-content.mdx
@@ -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
diff --git a/docs/en-US/react/index.mdx b/docs/en-US/react/index.mdx
index d363bfb..b582136 100644
--- a/docs/en-US/react/index.mdx
+++ b/docs/en-US/react/index.mdx
@@ -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`.
+
+ **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 {};
+ }
+ }
+ ```
+
+
---
## Step 4: Add the GTProvider to your app
@@ -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.
+
+ **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 (
+
+ {/* Your app content */}
+
+ );
+ }
+ ```
+
+
---
## Step 5: Mark content for translation