install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/TerminalSkills/skills/next-intl" ~/.claude/skills/comeonoliver-skillshub-next-intl && rm -rf "$T"
manifest:
skills/TerminalSkills/skills/next-intl/SKILL.mdsource content
next-intl
Overview
next-intl is the leading i18n library for Next.js App Router. It handles locale routing, message translation, date/number formatting, and works with both server and client components. ICU message syntax for plurals and variables.
Instructions
Step 1: Setup
npm install next-intl
// i18n/request.ts — Locale detection import { getRequestConfig } from 'next-intl/server' export default getRequestConfig(async ({ requestLocale }) => { const locale = await requestLocale || 'en' return { locale, messages: (await import(`../messages/${locale}.json`)).default, } })
// messages/en.json { "HomePage": { "title": "Welcome to {appName}", "description": "The best tool for {count, plural, one {# team} other {# teams}}", "cta": "Get Started" }, "Dashboard": { "greeting": "Hello, {name}", "lastLogin": "Last login: {date, date, medium}" } }
// messages/de.json { "HomePage": { "title": "Willkommen bei {appName}", "description": "Das beste Tool für {count, plural, one {# Team} other {# Teams}}", "cta": "Jetzt starten" } }
Step 2: Server Components
// app/[locale]/page.tsx — Translated server component import { useTranslations } from 'next-intl' export default function HomePage() { const t = useTranslations('HomePage') return ( <main> <h1>{t('title', { appName: 'MyApp' })}</h1> <p>{t('description', { count: 5000 })}</p> <a href="/signup">{t('cta')}</a> </main> ) }
Step 3: Middleware Routing
// middleware.ts — Locale routing import createMiddleware from 'next-intl/middleware' export default createMiddleware({ locales: ['en', 'de', 'fr', 'ja'], defaultLocale: 'en', localePrefix: 'as-needed', // /de/about but /about (for en) }) export const config = { matcher: ['/((?!api|_next|.*\\..*).*)'] }
Guidelines
- ICU message syntax:
for plurals.{count, plural, one {# item} other {# items}} - Server components: use
directly, no context needed.useTranslations() - Client components: wrap with
.NextIntlClientProvider - Keep message keys namespaced by page/component for maintainability.
- Use
to avoid /en/ prefix for default locale.localePrefix: 'as-needed'