> ## Documentation Index
> Fetch the complete documentation index at: https://docs.honyaku.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Example project

> See an example project and learn how to use honyaku.dev in a real project

Check out our example project at [https://example.honyaku.dev](https://example.honyaku.dev)

This example project is a multilingual recipe discovery app called **World Kitchen**, built with [Next.js](https://nextjs.org/) and [next-intl](https://next-intl.dev/). It uses honyaku.dev to automatically translate the app into 100+ languages via a GitHub Actions workflow.

You can find the full source code on [GitHub](https://github.com/honyaku-dev/honyaku-example).

## Project Structure

```
honyaku-example/
├── .github/workflows/
│   └── translate.yml          # GitHub Actions workflow for auto-translation
├── app/
│   └── [locale]/
│       ├── layout.tsx         # Root layout with locale support
│       └── page.tsx           # Home page
├── components/
│   ├── Header.tsx             # Header with locale switcher
│   ├── LocaleSwitcher.tsx     # Language selector dropdown
│   └── RecipeCard.tsx         # Recipe display card
├── i18n/
│   ├── navigation.ts          # Locale-aware navigation utilities
│   ├── request.ts             # Server-side i18n config
│   └── routing.ts             # Locale routing definition
├── lib/
│   ├── honyaku.ts             # Honyaku message format converter
│   └── recipes.ts             # Recipe data
├── messages/
│   ├── en.json                # English source translations
│   └── generated/
│       └── *.json             # Auto-generated translations (100+ languages)
├── next.config.ts             # Next.js config with next-intl plugin
└── proxy.ts                   # next-intl middleware
```

## Translation Source File

The source translation file uses the honyaku.dev format with `text` and `description` fields. The `description` provides context for the AI translator to produce more accurate translations.

```json messages/en.json theme={null}
{
  "header_title": {
    "text": "World Kitchen",
    "description": "App name shown in the header. A recipe discovery app for world cuisines."
  },
  "header_subtitle": {
    "text": "Discover recipes from around the world",
    "description": "Tagline shown below the app name in the header."
  },
  "home_page_hero_title": {
    "text": "Explore Global Flavors",
    "description": "Main heading on the home page hero section."
  },
  "recipe_card_cooking_time": {
    "text": "{minutes} min",
    "description": "Cooking time label on a recipe card. {minutes} is replaced with the number of minutes."
  },
  ...
}
```

## Honyaku Message Converter

Since next-intl expects simple `string` values, we need to convert the honyaku.dev format (with `text` and `description` fields) into plain strings. `loadMessages` extracts the `text` from each entry, and `loadLocale` handles loading the right file for each locale.

```ts lib/honyaku.ts theme={null}
import enMessages from "@/messages/en.json"

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

export async function loadLocale(locale: string) {
  if (locale === "en") {
    return loadMessages(enMessages)
  } else {
    return loadMessages((await import(`../messages/generated/${locale}.json`)).default)
  }
}
```

## i18n Setup

### Routing

Defines the supported locales from `@honyaku-dev/locales` (which provides metadata for 100+ languages) and sets English as the default.

```ts i18n/routing.ts theme={null}
import { defineRouting } from "next-intl/routing";
import locales from "@honyaku-dev/locales";

export const routing = defineRouting({
  locales: locales.map((locale) => locale.id),
  defaultLocale: "en",
});
```

### Request Configuration

Loads the appropriate translation file for each request. English messages are always spread as a fallback, so any missing translations in other languages will gracefully fall back to English.

```ts i18n/request.ts theme={null}
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,
    }
  };
});
```

## GitHub Actions Workflow

This workflow automatically translates the source file into all supported languages whenever `messages/en.json` is updated on the `main` branch. The `targets: "all:{id}.json"` pattern generates a separate file for each language.

```yaml .github/workflows/translate.yml theme={null}
name: Translate

on:
  workflow_dispatch:
  push:
    branches: [main]
    paths:
      - "messages/en.json"

permissions:
  contents: write

jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: honyaku-dev/honyaku-action@v1
        with:
          source-file: "messages/en.json"
          output-dir: "messages/generated"
          targets: "all:{id}.json"
          api-key: ${{ secrets.HONYAKU_API_KEY }}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.