zoonk-translations

📁 zoonk/zoonk 📅 1 day ago
0
总安装量
1
周安装量
安装命令
npx skills add https://github.com/zoonk/zoonk --skill zoonk-translations

Agent 安装分布

amp 1
opencode 1
cursor 1
kimi-cli 1
github-copilot 1

Skill 文档

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");

2. 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 });

3. 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"));

4. 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

  1. Add translation call in code:

    const t = await getTranslations();
    return <h1>{t("New page title")}</h1>;
    
  2. 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"
    }
    
  3. 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"
  }
}