zoonk-translations

Internationalization (i18n) Workflow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "zoonk-translations" with this command: npx skills add zoonk/zoonk/zoonk-zoonk-zoonk-translations

Internationalization (i18n) Workflow

Overview

This project uses next-intl for internationalization. Translations are stored in JSON message files.

Key Functions

  • Server Components: Use getTranslations (no locale needed)

  • Client Components: Use useTranslations

  • Metadata/Server Actions: Use getTranslations with locale parameter

Critical Rules

  1. No Dynamic Values in Translation Keys

IMPORTANT: The t function does NOT support dynamic values as keys.

// BAD: Dynamic key - will NOT work const category = getCategory(); t(category); // Error! t(MYLABELS[category]);

// GOOD: String literals only t("Arts courses"); t("Business courses"); t("Technology courses");

  1. String Interpolation IS Supported

You CAN use string interpolation for dynamic values within translations:

// GOOD: Interpolation with static key t("Explore all {category} courses", { category: "arts" }); t("Welcome, {name}!", { name: user.name }); t("{count} items remaining", { count: 5 });

  1. Don't Pass t Function Around

You can't pass the t function to other functions or components:

// BAD: Passing t function function myFunction(t, label) { return t(label); } myFunction(t, "Some label");

// GOOD: Call t directly function myFunction(translatedLabel: string) { return translatedLabel; } myFunction(t("Some label"));

  1. Locale Parameter Rules

// Server Component - no locale needed const t = await getTranslations(); t("Hello");

// generateMetadata - needs locale export async function generateMetadata({ params }) { const { locale } = await params; const t = await getTranslations({ locale }); return { title: t("Page Title") }; }

Workflow for Adding Translations

Add translation call in code:

const t = await getTranslations(); return <h1>{t("New page title")}</h1>;

Add the key to message files:

Find JSON message files in your locales directory (e.g., messages/en.json , messages/es.json ) and add the new key:

{ "New page title": "New page title" }

Translate for each locale:

// messages/es.json { "New page title": "Nuevo título de página" }

Common Patterns

Conditional Text

// Use separate translation keys const status = isActive ? t("Active") : t("Inactive");

Pluralization

// Use ICU message format t("items", { count: 5 }); // "5 items"

In your messages file:

{ "items": "{count, plural, =0 {No items} =1 {1 item} other {# items}}" }

Rich Text (with components)

t.rich("Read our {link}", { link: (chunks) => <Link href="/terms">{chunks}</Link>, });

In your messages file:

{ "Read our {link}": "Read our <link>terms of service</link>" }

File Structure

messages/ en.json # English translations es.json # Spanish translations pt.json # Portuguese translations

Namespaces

For larger apps, organize translations by namespace:

// Server Component const t = await getTranslations("Dashboard"); t("welcome"); // Looks up "Dashboard.welcome"

// Client Component const t = useTranslations("Dashboard"); t("welcome");

{ "Dashboard": { "welcome": "Welcome to your dashboard" } }

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

workflow

No summary provided by upstream source.

Repository SourceNeeds Review
General

cache-components

No summary provided by upstream source.

Repository SourceNeeds Review
General

next-cache-components

No summary provided by upstream source.

Repository SourceNeeds Review
General

zoonk-issue-writer

No summary provided by upstream source.

Repository SourceNeeds Review