General Translation  
Next.js

Dictionaries Reference

An overview of the Dictionary Pattern

Overview

In this reference guide, we will introduce you to the dictionary pattern. Please feel free to skip around this page as needed. We will cover the following:


What is a dictionary?

General Translation allows translatable content to be stored in a dictionary file. A dictionary is a nested object with string values that can be used to store translatable content. This dictionary file (.ts, .js, or .json) is then used to generate a translation.

Dictionaries can be used standalone, or in conjunction with <T> components.

Dictionary vs <T> Components

The dictionary pattern has a few advantages over the <T> component:

  1. Centralized Storage: Dictionaries store all translatable content in a single file, making it easier to manage and update.
  2. Historical Precedent: The dictionary pattern is a common design pattern in the industry and is used by many other libraries.

At the same time, it has some disadvantages as well:

  1. Complexity: Dictionaries are more complex to set up and use than the <T> component.
  2. Readability: Dictionaries are less readable than the <T> component because the content is not inline.

Both design patterns are supported by our library and are not mutually exclusive. You can use a dictionary along side <T> components.

Our advice

We recommend using the <T> component because of its simplicity especially if you are new to internationalization (i18n). We offer dictionary support for those who prefer this design pattern from past experiences or for ease of integration with existing code bases.


How to use dictionaries

In this section, we will show you how to set up a bare-bones dictionary implementation in your Next.js application. We will walk through the following steps:

Create a dictionary

Reference the dictionary

Step 1: Create a dictionary

The first step is to create a dictionary. This is a dictionary.js (.ts or .json) file that contains all the content you want to translate. Create the dictionary in your src/ directory.

dictionary.js <--- Add dictionary file here
middleware.js
next.config.js

If you are not using a src/ folder, you can also specify the directory of the dictionary in the next.config.js file.

Add the following content to your dictionary.js file:

src/dictionary.js
const dictionary = {
  greetings: {
    goodbye: 'Goodbye, World!'
  },
}
 
export default dictionary;

Step 2: Reference the dictionary

There are a few ways to use the dictionary, depending on the context where you are trying to use the dictionary. For example, if you are in a client-side component, use the useDict() hook and for server-side components use await getDict().

Here is an example of how to use the dictionary in a client-side component:

"use client";
import { useDict } from 'gt-next/client';
 
export default function MyComponent() {
 
  const d = useDict(); // on the client side, you use the useDict hook
 
  return (
    <div>
      {d('greetings.hello')}
    </div>
  );
}

And here is an example of how to access the translations in a server-side component:

import { getDict } from 'gt-next/server';
 
export default async function MyComponent() {
 
  const d = await getDict(); // on the server side, you have to await a promise
 
  return (
    <div>
      {d('greetings.hello')}
    </div>
  );
}

Using dictionaries

Variables

You can add variables to your dictionary by using the {variable} syntax:

src/dictionary.js
const dictionary = {
  greetings: {
    hello: 'Hello, {name}!',
    goodbye: 'Goodbye, {name}!'
  },
}
export default dictionary;
src/components/MyComponent.js
import { getDict } from 'gt-next/server';
 
export default async function MyComponent() {
  const d = await getDict();
 
  return (
    <div>
      {d('greetings.hello', { variables: { name: 'World' }})}
      {d('greetings.goodbye', { variables: { name: 'World' }})}
    </div>
  );
}

Read more about adding variables to your dictionary in the DictionaryTranslationOptions type.

Prefixes

Additionally, with useDict() and getDict() you can pass in a prefix to the function to specify a shared path in the dictionary. This is useful if you have a shared path in your dictionary that you want to use in multiple components.

const dictionary = {
  greetings: {
    common: {
      hello: 'Hello, World!',
      goodbye: 'Goodbye, World!'
    },
  },
}
export default dictionary;
src/components/MyComponent.js
import { getDict } from 'gt-next/server';
 
export default async function MyComponent() {
  // All translation paths such as 'hello' will be prefixed with 'greetings'
  const d = await getDict('greetings.common'); 
 
  return (
    <div>
      {d('hello')} {/* hello -> greetings.common.hello */}
      {d('goodbye')} {/* goodbye -> greetings.common.goodbye */}
    </div>
  );
}

Subsets with <GTProvider>

You can also specify a prefix in the <GTProvider> component. This will pass a subset of the dictionary to the client, so the whole dictionary does not have to be loaded. This only applies to client side components.

layout.js
import { GTProvider } from 'gt-next';
 
export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                <GTProvider id="nested.dictionary.key">
                    {children}
                </GTProvider>
            </body>
        </html>
    );
}

You still have to specify the entire path when referencing a key in the dictionary.

"use client";
 
import { useDict } from 'gt-next/client';
 
export default function MyComponent() {
  const d = useDict();
 
  return (
    <div>
      {d('nested.dictionary.key.greeting')}
    </div>
  );
}

Production considerations

Deploying to production

Make sure to run the translate command before deploying to production, so that all translations are available at runtime. We recommend adding it to your in your CD pipeline or as a part of your build script.

package.json
{
  "scripts": {
    "build": "npx gt-next-cli translate --languages fr es ja && <YOUR_BUILD_COMMAND>",
  }
}

That's it! You have successfully translated your application into French, Spanish, and Japanese.

For a more detailed guide on deploying your application, please refer to the Deployment guide. For more information on the command, please refer to the CLI Tool reference guide.

Behavior: Development vs Production

In development, the d() function will translate dictionary entries on-demand. This means that when the component is rendered, it will perform a translation immediately. We do this for convenience to make development with other languages easier.

To enable this behavior, just add a Dev API key to your environment.

In production, the d() function will translate content at build time. This means that you have to run the translation command before deploying your application.

Tip: If you want to simulate production behavior in development, just use a production API key in your development build.


Notes

  • Dictionaries are an alternative to the <T> component. They can be used in conjunction with <T> components or standalone.
  • Dictionary translations occur at build time, so you have to add the translate command to your build process.
  • Dictionaries can be used with prefixes to specify a subset of the dictionary.

Next steps

On this page