Translating Strings

How to internationalize strings

Overview

This guide will walk you through how to internationalize strings in your Next.js app using the useGT() hook & getGT() function.

We will cover the following:

When to use the useGT() hook

How to use the useGT() hook

Using variables

Examples

Common pitfalls

In this guide, when we refer to the useGT() hook, we are also referring to the getGT() function.

The only difference between the two is when to use them.

The getGT() function is an asynchronous server-side function that returns a promised function, while the useGT() hook returns the function directly.

Use the getGT() function in server components, and the useGT() hook in client components.

src/app/page.tsx
import { getGT } from 'gt-next/server';
export async function MyComponent() {
  const translate = await getGT();
  const translatedString = translate('Hello, world!');
  return <div>{translatedString}</div>;
}
src/app/page.tsx
'use client';
import { useGT } from 'gt-next/client';
export function MyComponent() {
  const translate = useGT();
  const translatedString = translate('Hello, world!');
  return <div>{translatedString}</div>;
}

When to use the useGT() hook

The useGT() hook is a React hook that can be used to translate strings.

In most cases, you can use the <T> component. However, in cases where JSX is not appropriate, the useGT() hook can be used.

Some cases where the useGT() hook could be more appropriate are:

  • In properties that expect strictly strings, such as placeholder or title attributes.
  • When the string is part of a larger object, for example:
const user = {
  title: 'Mr.',
  name: 'John',
  description: 'John is a software engineer at General Translation',
}

Here, only the description property should be translated.

Wherever possible, you should use the <T> component. The <T> component allows you to translate JSX content, and is the recommended way to translate strings.


How to use the useGT() hook

The useGT() hook has to be called within the <GTProvider>.

To translate a string, simply pass the string directly to the function returned by the hook.

import { useGT } from 'gt-next/client';
export function MyComponent() {
  const translate = useGT();
  return <div>{translate('Hello, world!')}</div>;
}

Unlike traditional i18n libraries, the useGT() hook does not require you to pass a key to the function. Instead, the string is passed directly to the function.

This means that you don't need to use dictionaries!

How to use the getGT() function

On the other hand, since the getGT() function is an asynchronous server-side function, it can be used in server components, and does not need to be called within the <GTProvider>.

The context for getGT() is handed by the withGTConfig function in your next.config.ts file.

import { getGT } from 'gt-next/server';
export async function MyComponent() {
  const translate = await getGT();
  return <div>{translate('Hello, world!')}</div>;
}

Using variables

Often, you will need to translate strings that contain variables.

For example, you may need to translate a string that contains numerical values.

To add variables, simply add the variable to the string as a placeholder with {variable}, and pass an object as the second argument to the function returned by the hook.

const price = 100;
const translate = useGT();
translate('There are {count} items in the cart', { variables: { count: 10 } });

The {count} placeholder will be replaced with the value of the count variable.

This allows you to display dynamic values in your translations.

For more information on the API, see the API reference.


Examples

  1. Translating a string in a component
import { useGT } from 'gt-next/client';

export default function MyComponent() {
  const t = useGT();
  return (
    <div>
      <h1>{t('Hello, world!')}</h1>
    </div>
  )
}
export default function MyComponent() {
  return (
    <div>
      <h1>Hello, world!</h1>
    </div>
  )
}
  1. Translating a string with variables
import { useGT } from 'gt-next/client';

export default function MyComponent() {
  const t = useGT();
  const count = 10;
  return (
    <div>
      <h1>{t('There are {count} items in the cart', { variables: { count } })}</h1>
    </div>
  )
}
export default function MyComponent() {
  const count = 10;
  return (
    <div>
      <h1>There are {count} items in the cart</h1>
    </div>
  )
}
  1. Translating parts of an object
import { useGT } from 'gt-next/client';

export default function MyComponent() {
  const t = useGT();
  const users = [
    {
      name: 'John',
      description: t('John is a software engineer at General Translation'),
    },
    {
      name: 'Jane',
      description: t('Jane is a software engineer at Google'),
    },
  ]
  return (
    <div>
      {users.map((user) => (
        <div key={user.name}>
          <h1>{user.name}</h1>
          <p>{user.description}</p>
        </div>
      ))}
    </div>
  )
}
export default function MyComponent() {
  const users = [
    {
      name: 'John',
      description: 'John is a software engineer at General Translation',
    },
    {
      name: 'Jane',
      description: 'Jane is a software engineer at Google',
    },
  ]
  return (
    <div>
      {users.map((user) => (
        <div key={user.name}>
          <h1>{user.name}</h1>
          <p>{user.description}</p>
        </div>
      ))}
    </div>
  )
}
  1. Translating shared constants
src/llms.ts
import { useGT } from 'gt-next/client';
// Custom hook to get LLM data with translations
export function useLLMData() {
  const t = useGT();
  return [
    {
      name: 'GPT-4.1',
      id: 'gpt-4.1',
      description: t('GPT-4.1 is a large language model developed by OpenAI'),
    },
    {
      name: 'Claude 3.7 Sonnet',
      id: 'claude-3-7-sonnet',
      description: t('Claude 3.7 Sonnet is a large language model developed by Anthropic'),
    },
  ]
}
import { useLLMData } from './llms';

export default function MyComponent() {
  const llms = useLLMData();
  return (
    <div>
      {llms.map((llm) => (
        <div key={llm.id}>
          <h1>{llm.name}</h1>
          <p>{llm.description}</p>
        </div>
      ))}
    </div>
  )
}
src/llms.ts
export const llms = [
  {
    name: 'GPT-4.1',
    id: 'gpt-4.1',
    description: 'GPT-4.1 is a large language model developed by OpenAI',
  },
  {
    name: 'Claude 3.7 Sonnet',
    id: 'claude-3-7-sonnet',
    description: 'Claude 3.7 Sonnet is a large language model developed by Anthropic',
  },
]
import { llms } from './llms';

export default function MyComponent() {
  return (
    <div>
      {llms.map((llm) => (
        <div key={llm.id}>
          <h1>{llm.name}</h1>
          <p>{llm.description}</p>
        </div>
      ))}
    </div>
  )
}

Be careful! In this last example, you have to be very careful about how you use the useGT() hook. Make sure that it doesn't violate the rules of React.

Additionally, make sure that the useGT() hook is called within the React context. If your constants are defined outside of a React component, you will likely need to create a custom hook to access your data with translations.


Common Pitfalls

Translating Dynamic Content

All strings must be known at build time.

This means that you cannot translate dynamic content that is generated or retrieved at runtime.

This includes variables, even if they are strings.

export default function MyComponent() {
  const [dynamicContent, setDynamicContent] = useState('Hello, world!');
  const t = useGT();
  return (
    <div>
      <h1>{t(dynamicContent)}</h1> {/* This will not work */}
    </div>
  )
}

The CLI tool will warn you if you try to translate dynamic content with the useGT() hook.


Next Steps

How is this guide?