Receber por email
← Voltar para o catálogo

i18n-automation

Automate internationalization and localization workflows for web applications with translation, key generation, and library setup

367estrelas
Atualizado há 4 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add aiskillstore/marketplace

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/i18n-automation/svg)](https://www.skillteca.com.br/skills/i18n-automation)

Skills relacionadas

Ver todas de Segurança →

Alerta por categoria

Receba novas skills de Segurança toda segunda

1 email curto, só com as skills novas de Segurança. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

i18n Automation

Purpose

Automate complete internationalization workflows including translation, key-value generation, library installation, and locale configuration for web applications.

Specialist Agent

I am an internationalization specialist with expertise in:

  • i18n library selection and configuration (react-i18n, next-intl, i18next)
  • Translation key architecture and organization
  • Locale file formats (JSON, YAML, PO, XLIFF)
  • RTL (Right-to-Left) language support
  • SEO and metadata localization
  • Dynamic content translation strategies

Methodology (Plan-and-Solve Pattern)

  1. Analyze Project: Detect framework, existing i18n setup, content to translate
  2. Design i18n Architecture: Choose library, key structure, file organization
  3. Extract Content: Identify all translatable strings and create keys
  4. Generate Translations: Create locale files with translations
  5. Configure Integration: Set up routing, language detection, switcher component
  6. Validate: Test all locales, check RTL, verify SEO metadata

Framework Support

Next.js (Recommended: next-intl):

// Installation
npm install next-intl

// Configuration: next.config.js
const createNextIntlPlugin = require('next-intl/plugin');
const withNextIntl = createNextIntlPlugin();

module.exports = withNextIntl({
  i18n: {
    locales: ['en', 'ja', 'es', 'fr'],
    defaultLocale: 'en'
  }
});

// File structure
/messages
  /en.json
  /ja.json
  /es.json
  /fr.json

React (Recommended: react-i18next):

// Installation
npm install react-i18next i18next

// Configuration: i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

i18n
  .use(initReactI18next)
  .init({
    resources: {
      en: { translation: require('./locales/en.json') },
      ja: { translation: require('./locales/ja.json') }
    },
    lng: 'en',
    fallbackLng: 'en',
    interpolation: { escapeValue: false }
  });

Vue (Recommended: vue-i18n):

// Installation
npm install vue-i18n

// Configuration
import { createI18n } from 'vue-i18n';

const i18n = createI18n({
  locale: 'en',
  messages: {
    en: require('./locales/en.json'),
    ja: require('./locales/ja.json')
  }
});

Translation Key Architecture

Namespace Organization:

{
  "common": {
    "buttons": {
      "submit": "Submit",
      "cancel": "Cancel",
      "save": "Save"
    },
    "errors": {
      "required": "This field is required",
      "invalid_email": "Invalid email address"
    }
  },
  "landing": {
    "hero": {
      "title": "Welcome to Our Product",
      "subtitle": "The best solution for your needs",
      "cta": "Get Started"
    },
    "features": {
      "feature1_title": "Fast Performance",
      "feature1_desc": "Lightning-fast response times"
    }
  },
  "pricing": {
    "tiers": {
      "free": "Free",
      "pro": "Pro",
      "enterprise": "Enterprise"
    }
  }
}

Flat vs Nested Keys:

// Nested (Recommended for organization)
{
  "user": {
    "profile": {
      "title": "Profile",
      "edit": "Edit Profile"
    }
  }
}

// Flat (Simpler, some libraries prefer)
{
  "user.profile.title": "Profile",
  "user.profile.edit": "Edit Profile"
}

Translation Strategies

Strategy 1: Professional Translation

  • Extract keys to XLIFF or JSON
  • Send to translation service (Locize, Crowdin, Phrase)
  • Import translated files
  • High quality, costs money

Strategy 2: AI Translation (Good for MVP)

  • Use Claude/GPT to translate
  • Review by native speaker recommended
  • Fast and cost-effective
  • May miss cultural nuances

Strategy 3: Community Translation

  • Open source projects
  • Contributor PRs with translations
  • Review process for quality
  • Builds community engagement

Strategy 4: Hybrid

  • AI for initial translation
  • Professional review for key pages
  • Community contributions for edge cases
  • Best balance of speed/quality/cost

Language-Specific Considerations

Japanese (ja):

{
  "formality": {
    "casual": "ありがとう",
    "polite": "ありがとうございます",
    "honorific": "ありがとうございました"
  },
  "context_matters": "Japanese uses different words based on context",
  "character_counts": "Japanese characters more information-dense than English"
}

Spanish (es):

{
  "variants": {
    "es-ES": "Spain Spanish",
    "es-MX": "Mexican Spanish",
    "es-AR": "Argentine Spanish"
  },
  "formality": {
    "informal_you": "tú",
    "formal_you": "usted"
  }
}

Arabic (ar) - RTL:

{
  "direction": "rtl",
  "text_align": "right",
  "special_handling": "Needs RTL CSS and mirrored layouts"
}

German (de):

{
  "compound_words": "German combines words: Datenschutzerklärung",
  "formal_vs_informal": {
    "informal": "du",
    "formal": "Sie"
  }
}

SEO and Metadata Localization

Next.js Metadata:

// app/[locale]/layout.tsx
export async function generateMetadata({ params: { locale } }) {
  const t = await getTranslations({ locale, namespace: 'metadata' });

  return {
    title: t('title'),
    description: t('description'),
    keywords: t('keywords'),
    openGraph: {
      title: t('og_title'),
      description: t('og_description'),
      images: [t('og_image')]
    },
    alternates: {
      canonical: `https://example.com/${locale}`,
      languages: {
        'en': 'https://example.com/en',
        'ja': 'https://example.com/ja',
        'es': 'https://example.com/es'
      }
    }
  };
}

Sitemap Localization:

<!-- sitemap.xml -->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://example.com/en/</loc>
    <xhtml:link rel="alternate" hreflang="ja" href="https://example.com/ja/"/>
    <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/"/>
  </url>
</urlset>

Language Switcher Component

Next.js Example:

// components/LanguageSwitcher.tsx
import { useLocale } from 'next-intl';
import { usePathname, useRouter } from 'next/navigation';

const languages = {
  en: { name: 'English', flag: '🇺🇸' },
  ja: { name: '日本語', flag: '🇯🇵' },
  es: { name: 'Español', flag: '🇪🇸' },
  fr: { name: 'Français', flag: '🇫🇷' }
};

export default function LanguageSwitcher() {
  const locale = useLocale();
  const router = useRouter();
  const pathname = usePathname();

  const switchLanguage = (newLocale: string) => {
    const newPath = pathname.replace(`/${locale}`, `/${newLocale}`);
    router.push(newPath);
  };

  return (
    <select value={locale} onChange={(e) => switchLanguage(e.target.value)}>
      {Object.entries(languages).map(([code, { name, flag }]) => (
        <option key={code} value={code}>
          {flag} {name}
        </option>
      ))}
    </select>
  );
}

RTL Support

CSS for RTL:

/* Automatic RTL with logical properties */
.container {
  margin-inline-start: 1rem;  /* Left in LTR, Right in RTL */
  padding-inline-end: 2rem;   /* Right in LTR, Left in RTL */
}

/* Direction-specific overrides */
[dir="rtl"] .special-element {
  transform: scaleX(-1);  /* Mirror icons/images */
}

Next.js RTL Detection:

// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

const rtlLocales = ['ar', 'he', 'fa'];

export function middleware(request: NextRequest) {
  const locale = request.nextUrl.pathname.split('/')[1];
  const response = NextResponse.next();

  if (rtlLocales.includes(locale)) {
    response.headers.set('dir', 'rtl');
  }

  return response;
}

Automation Workflow

Step 1: Extract Strings

// Scan all components for hardcoded strings
// Generate translation keys automatically
// Create skeleton locale files

Step 2: Generate Translations

// For each target language:
//   - Translate using AI or service
//   - Preserve placeholders: {name}, {count}
//   -
Compartilhar X LinkedIn