Skills Agentes

I18n

Añade internacionalización (i18n) completa a un proyecto Next.js con next-intl: soporta 14+ idiomas, enrutamiento de locales SEO-friendly, sitemaps con hreflang y traducción masiva.

Reemplaza a: next-i18next

Estrellas
688

en todo el repo

Actividad
35

0–100, la ruta de este skill

Actualizado
hace 5 meses

último commit aquí

Commits
0

últimos 90 días

Contexto
2.4k tok

81 tok en reposo

Paquete
1 archivo

9 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add OpenClaudia/openclaudia-skills --skill i18n --agent claude-code

Se instala solo en este repositorio.

Este skill makes network requests.

Qué hace

  • Instala y configura next-intl v4 en un proyecto Next.js con App Router (config, routing, navigation, request, middleware)
  • Crea la ruta dinámica [locale] con generateStaticParams y setRequestLocale
  • Extrae strings hardcodeados a archivos de traducción en src/messages/{locale}.json
  • Traduce a múltiples locales usando agentes Codex en paralelo vía codex-tasks
  • Actualiza el sitemap con alternates hreflang por página, no por locale

Úsalo cuando

  • El usuario pide 'internacionalizar', 'add i18n', 'add translations', 'multi-language', 'localize', 'add language support' o 'translate my site'

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • Internacionaliza este proyecto Next.js con next-intl
    • Añade soporte multilenguaje a mi sitio
    • Quiero traducir mi web a varios idiomas con hreflang

    SKILL.md

    En inglés

    Internationalize a Next.js Project

    Add complete internationalization to a Next.js (App Router) project using next-intl v4. This skill handles routing, translation files, sitemap hreflang, and bulk translation across all locales.

    Step 1: Assess the Project

    1. Check the Next.js version (package.json) — must be 13+ with App Router
    2. Check if i18n is already partially set up (look for next-intl, next-i18next, [locale] routes)
    3. Identify all pages/routes that need translation
    4. Identify all user-facing strings (hardcoded text in components)
    5. Ask the user which locales to support (default recommendation: en, es, fr, de, pt, ja, ar, zh, zh-tw, id, vi, ms, ru, hi)

    Step 2: Install Dependencies

    npm install next-intl
    

    Step 3: Create i18n Configuration Files

    Create 4 files under src/i18n/:

    src/i18n/config.ts

    export const locales = ['en', 'es', 'fr', 'de', 'pt', 'ja', 'ar', 'zh', 'zh-tw', 'id', 'vi', 'ms', 'ru', 'hi'] as const
    
    export type Locale = (typeof locales)[number]
    export const defaultLocale: Locale = 'en'
    
    export const localeNames: Record<Locale, string> = {
      en: 'English',
      es: 'Espanol',
      fr: 'Francais',
      de: 'Deutsch',
      pt: 'Portugues',
      ja: '日本語',
      ar: 'العربية',
      zh: '简体中文',
      'zh-tw': '繁體中文',
      id: 'Bahasa Indonesia',
      vi: 'Tieng Viet',
      ms: 'Bahasa Melayu',
      ru: 'Русский',
      hi: 'हिन्दी',
    }
    
    export const rtlLocales: Locale[] = ['ar']
    

    src/i18n/routing.ts

    import { defineRouting } from 'next-intl/routing'
    import { defaultLocale, locales } from './config'
    
    export const routing = defineRouting({
      locales,
      defaultLocale,
      localePrefix: 'as-needed', // English URLs stay clean, other locales get /es/, /fr/, etc.
    })
    

    src/i18n/navigation.ts

    import { createNavigation } from 'next-intl/navigation'
    import { routing } from './routing'
    
    export const { Link, redirect, usePathname, useRouter } = createNavigation(routing)
    

    src/i18n/request.ts

    import { getRequestConfig } from 'next-intl/server'
    import { routing } from './routing'
    
    export default getRequestConfig(async ({ requestLocale }) => {
      let locale = await requestLocale
      if (!locale || !routing.locales.includes(locale as any)) {
        locale = routing.defaultLocale
      }
      return {
        locale,
        messages: (await import(`../messages/${locale}.json`)).default,
      }
    })
    

    Step 4: Create Middleware

    Create src/middleware.ts:

    import createMiddleware from 'next-intl/middleware'
    import { routing } from '@/i18n/routing'
    
    export default createMiddleware({
      ...routing,
      localeDetection: false, // Don't auto-redirect based on Accept-Language
    })
    
    export const config = {
      matcher: ['/((?!_next|api|images|fonts|favicon|sitemap|robots).*)'],
    }
    

    Key decision: localeDetection: false prevents auto-redirecting users based on browser language. This keeps English URLs stable for SEO. Users can manually switch languages via a language selector.

    Step 5: Update next.config

    Wrap the existing config with createNextIntlPlugin:

    import createNextIntlPlugin from 'next-intl/plugin'
    const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts')
    
    // ... existing config ...
    export default withNextIntl(nextConfig)
    

    Step 6: Add [locale] Dynamic Route

    Move all page content under src/app/[locale]/:

    1. Create src/app/[locale]/layout.tsx with:

      • generateStaticParams() returning all locales
      • setRequestLocale(locale) call
      • <NextIntlClientProvider> wrapping children
      • <html lang={locale} dir={rtlLocales.includes(locale) ? 'rtl' : 'ltr'}>
      • Hreflang <link> tags in <head> for all locales + x-default
    2. Move existing pages into src/app/[locale]/

    3. Each page should call setRequestLocale(locale) for static generation

    Step 7: Extract Strings into Translation Files

    1. Create src/messages/en.json with all user-facing strings organized by section:

      {
        "common": { "signIn": "Sign In", ... },
        "tools": { "tool-slug": { "title": "...", "description": "..." } },
        "faq": { "tool-slug": [{ "question": "...", "answer": "..." }] }
      }
      
    2. Replace all hardcoded strings in components with useTranslations():

      const t = useTranslations('common')
      return <button>{t('signIn')}</button>
      
    3. For server components, use getTranslations():

      const t = await getTranslations('common')
      

    Step 8: Translate to All Locales

    For each non-English locale, create src/messages/{locale}.json with the same structure as en.json.

    Translation Strategy

    Use parallel Codex agents via the codex-tasks skill to save Claude credits:

    1. Launch one Codex task per locale (up to 7 in parallel) using /codex-tasks
    2. Each task reads en.json, translates all strings, writes {locale}.json
    3. Codex prompt should include:
      • The full en.json content (or path to read it)
      • Target language name and locale code
      • Instructions:
        • Translate naturally, not literally
        • Keep technical terms in English (PowerPoint, PDF, API, etc.)
        • Preserve JSON structure exactly (same keys, same nesting)
        • Preserve interpolation variables like {count}, {name} unchanged
        • Write the result to src/messages/{locale}.json
    4. After Codex tasks complete, verify the results using the verification script below — Codex output quality varies and must be checked

    Verification

    After translation, run a verification script to catch issues:

    import json
    
    locales = ['es', 'fr', 'de', 'pt', 'ja', 'ar', 'zh', 'zh-tw', 'id', 'vi', 'ms', 'ru', 'hi']
    english_words = ['the ', 'and ', 'you ', 'your ', 'our ', 'this ', 'that ', 'with ', 'from ', 'will ']
    
    with open('src/messages/en.json') as f:
        en = json.load(f)
    
    for loc in locales:
        with open(f'src/messages/{loc}.json') as f:
            data = json.load(f)
    
        # Check: missing sections
        missing = [s for s in en if s not in data]
    
        # Check: residual English content
        eng_count = 0
        def check(d):
            nonlocal eng_count  # won't work in inline script; use list trick
            if isinstance(d, dict):
                for v in d.values(): check(v)
            elif isinstance(d, str):
                if sum(1 for w in english_words if w in d.lower()) >= 3:
                    eng_count += 1
        check(data)
    
        status = 'OK' if not missing and eng_count == 0 else 'ISSUES'
        print(f'{loc}: {status} (missing={len(missing)}, english={eng_count})')
    

    Step 9: Update Sitemap with Hreflang

    Update src/app/sitemap.ts to include hreflang alternates:

    import { MetadataRoute } from 'next'
    import { locales } from '@/i18n/config'
    
    const baseUrl = 'https://www.example.com'
    
    function buildAlternates(path: string): Record<string, string> {
      const alternates: Record<string, string> = {}
      for (const locale of locales) {
        const prefix = locale === 'en' ? '' : `/${locale}`
        alternates[locale] = `${baseUrl}${prefix}${path}`
      }
      return alternates
    }
    
    export default function sitemap(): MetadataRoute.Sitemap {
      return pages.map((path) => ({
        url: `${baseUrl}${path}`,
        lastModified: new Date(),
        alternates: { languages: buildAlternates(path) },
      }))
    }
    

    Important: Generate one canonical URL per page with hreflang alternates, NOT one URL per locale. This prevents duplicate content in search results.

    Step 10: Add Language Selector (Optional)

    Add a language switcher component that uses useRouter and usePathname from @/i18n/navigation to switch locales while preserving the current path.

    Step 11: Verify

    1. Build the project: npm run build — check that all static pages generate correctly
    2. Test English URLs have no prefix: https://example.com/tools
    3. Test locale URLs have prefix: https://example.com/es/tools
    4. Verify sitemap has hreflang alternates
    5. Check RTL rendering for Arabic
    6. Run the translation verification script from Step 8

    Common Pitfalls

    • public/sitemap.xml conflicts with dynamic src/app/sitemap.ts in dev mode — delete the static one or rename it
    • Middleware matcher must exclude _next, api, sitemap, robots, and static asset paths
    • localePrefix: 'as-needed' is critical — it keeps default locale URLs clean for SEO continuity
    • localeDetection: false prevents unwanted redirects that break SEO and confuse users
    • Large translation files (5000+ lines per locale) can make git pushes fail — use git config http.postBuffer 524288000
    • Verify translations thoroughly — automated translation often produces mixed-language output; always verify with the English word detection script after Codex tasks complete

    Locale Count Reference

    • 14 locales x N pages = 14N static pages at build time
    • Each locale JSON file is typically 2-5x the size of en.json (CJK characters, verbose languages)
    • Build time increases linearly with locale count

    Reproducido de OpenClaudia/openclaudia-skills bajo licencia MIT. Leer esta página en markdown.

    Archivos

    1 archivo en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Antes de instalar

    Requiere un proyecto Next.js 13+ con App Router, y next-intl instalado vía npm.

    Necesita en el PATH:npm

    Detalles

    Licencia
    MIT
    Recursos incluidos
    Solo SKILL.md
    Código fuente
    Ver SKILL.md

    Más de OpenClaudia/openclaudia-skills

    Este repo incluye 76 skills. Si instalas uno, normalmente ya tienes los demás. Ver el pack openclaudia-skills entero y su comando de instalación

    Genera un informe HTML autocontenible de tráfico competitivo: visitas mensuales (SimilarWeb), tráfico orgánico y Domain Rating (Ahrefs), con gráficos ranked, tendencias y tabla de datos.

    Costo de contexto al activarse
    1.2k tok
    Tamaño del paquete
    4 archivos
    Última actualización
    hace 3 días
    seo geo

    Obtiene datos de marca (nombre, descripción, logos, industria) desde la API de brand.dev y guarda los logos localmente.

    Costo de contexto al activarse
    702 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    datos analitica

    Audita TODAS las propiedades de Google Search Console a la vez: ranking por clics e impresiones con deltas, y diff de keywords por sitio (nuevas, suben, bajan, perdidas, o bien rankeadas sin clics).

    Costo de contexto al activarse
    1k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    el mes pasado
    seo geo

    Edita audio o video de podcast: recorta charla previa/posterior, quita muletillas, corta silencios, mejora el audio y aplica el mismo corte a una versión en video.

    Costo de contexto al activarse
    6k tok
    Tamaño del paquete
    3 archivos
    Última actualización
    el mes pasado
    redaccion contenido

    Clasifica y resume el feed de WeChat Moments (朋友圈) del usuario para que los eventos reales y la información genuina destaquen sobre la promoción, ponderando según cuánto le escribe el usuario a cada autor.

    Costo de contexto al activarse
    1.2k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    redes sociales

    Genera un informe de Citaciones de IA (GEO) para un dominio: qué prompts de búsqueda con IA citan el sitio en Google AI Overview y ChatGPT, con contexto de tráfico orgánico y cobertura por artículo.

    Costo de contexto al activarse
    840 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    seo geo

    Skills relacionados

    Úsalo cuando la implementación esté completa, todos los tests pasen, y necesites decidir cómo integrar el trabajo.

    Costo de contexto al activarse
    1.9k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 29 días
    herramientas desarrollo

    Úsalo al empezar trabajo de feature que necesita aislamiento del workspace actual, o antes de ejecutar planes de implementación: asegura un workspace aislado vía herramientas nativas o fallback a git worktree.

    Costo de contexto al activarse
    1.7k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 2 meses
    herramientas desarrollo

    Úsala al crear nuevas skills, editar skills existentes o verificar que funcionan antes de desplegarlas.

    Costo de contexto al activarse
    6.6k tok
    Tamaño del paquete
    7 archivos
    Última actualización
    hace 29 días
    herramientas desarrollo