Skip to main content

Next.js Integration

Generate translated message files during the build and serve them from Server Components.

Features

App Router and Pages Router both work — it is just JSON
Translation runs in the build step, not in a request
No key ever reaches the client bundle
Pairs with next-intl or i18next

Prerequisites

  • 1.Next.js 13 or newer
  • 2.An LLM API key used at build time only

Installation

npm install -D @shipi18n/cli

Configuration

Translate as part of the build script:

{
  "scripts": {
    "i18n": "shipi18n translate messages/en.json -t es,fr,de --incremental",
    "build": "npm run i18n && next build"
  }
}

Usage

const messages = (await import(`../messages/${locale}.json`)).default

Examples

Load messages in a Server Component

// app/[locale]/layout.jsx
export default async function LocaleLayout({ children, params: { locale } }) {
  const messages = (await import(`../../messages/${locale}.json`)).default

  return (
    <html lang={locale}>
      <body>
        <Provider messages={messages} locale={locale}>{children}</Provider>
      </body>
    </html>
  )
}

Pre-render every locale

export function generateStaticParams() {
  return ['en', 'es', 'fr', 'de'].map((locale) => ({ locale }))
}

Best Practices

  • Keep the translate step in the build script so Vercel and CI both pick it up.
  • Commit generated messages — build-time model calls make deploys flaky and slow.
  • Use generateStaticParams so every locale is statically rendered.

Troubleshooting

Module not found for a locale file

The translate step has not run for that language yet. Add it to -t and re-run npm run i18n.

The build calls the model on every deploy

Commit the generated files and use --incremental; unchanged keys are then skipped entirely.