Skip to main content

Creating a language file

We support any i18n library. However, to help AI understand the context and generate better translations, we recommend having “description” fields in your translation files to provide more context for each translation key.

Pattern 1

Schema:
Record<string, { text: string; description: string }>
Example:
{
  "save": {
    "text": "Save",
    "description": "A button label that allows users to save their changes or progress."
  },
  "cancel": {
      "text": "Cancel",
      "description": "A button label that allows users to abort an action or close a dialog without making changes."
  },
}
You can convert this format to a simpler format that your i18n library uses:
import en from "@/i18n/en.json"

const enMessages = loadMessages(en)

function loadMessages(messages: Record<string, { text: string }>): Record<string, string> {
  return Object.fromEntries(Object.entries(messages).map(([key, value]) => [key, value.text]))
}

Pattern 2

Schema:
{ key: string; text: string; description: string }[]
Example:
[
  {
    "key": "save",
    "text": "Save",
    "description": "A button label that allows users to save their changes or progress."
  },
  {
    "key": "cancel",
    "text": "Cancel",
    "description": "A button label that allows users to abort an action or close a dialog without making changes."
  },
]
You can convert this format to a simpler format that your i18n library uses:
import en from "@/i18n/en.json"

const enMessages = loadMessages(en)

function loadMessages(messages: { key: string; text: string }[]): Record<string, string> {
  return Object.fromEntries(messages.map(({ key, text }) => [key, text]))
}

Generating translations

For generating translations, it’s highly recommended to use one of our integrations. You can edit translations manually using our web editor if you find any mistakes. If you need a list of available locales for locale switcher or other purposes, check out @honyaku-dev/locales package.

Loading translations

Using our integration with CI/CD, you can automatically update translations when new translation keys are added, or when messages are modified. After new translations are generated, the changes are automatically committed to your repository. Because there is some delay before those changes are committed, it is highly recommended to prepare a fallback mechanism when loading translations. You can use a code snippet from our example project.
request.ts
import { getRequestConfig } from "next-intl/server";
import { hasLocale } from "next-intl";
import { routing } from "./routing";
import { loadLocale, loadMessages } from "@/lib/honyaku";
import en from "@/messages/en.json"

const enMessages = loadMessages(en);

export default getRequestConfig(async ({ requestLocale }) => {
  const requested = await requestLocale;
  const locale = hasLocale(routing.locales, requested)
    ? requested
    : routing.defaultLocale;

  const messages = await loadLocale(locale);
  return {
    locale,
    messages: {
      ...enMessages,
      ...messages,
    }
  };
});

Updating translations

If you use coding agents, you can use our update-translations skill. Install the skill by simply running this command:
npx skills add honyaku-dev/update-translations
Every time a coding agent inserts a new user message, it will update the language file using this skill. Alternatively, you can manually trigger /update-translations and let the coding agent read unstaged / uncommitted changes and update the language file accordingly.