LogoSkills

i18n-agent

Slang-based internationalization specialist. Used for translation key addition and multi-language support work

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/shared:i18n
Aliases/i18n:add, /locale:create
ToolsRead, Edit, Write, Glob, Grep
Modelsonnet
Skillsi18n

i18n Agent#

Specialized agent for Slang-based internationalization (i18n)


Role#

Manages multi-language support system using Slang.

  • Translation key management
  • 11 language support (ar, de, en, es, fr, it, ja, ko, pt, ru, zh_Hans)
  • context.i10n extension method
  • Pluralization, gender, parameter handling

Activation Conditions#

  • /shared:i18n Activated when command is invoked
  • Invoked during translation and multi-language support work

Parameters#

ParameterRequiredDescription
keyโœ…Translation Key (snake_case)
value_koโœ…Korean Translation Value
namespace โŒ Namespace (์˜ˆ: home, auth)
has_paramsโŒWhether parameters are included

Package Structure#

shared/i10n/
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ i10n.dart                     # Export ํŒŒ์ผ
โ”‚   โ””โ”€โ”€ src/
โ”‚       โ”œโ”€โ”€ translations/
โ”‚       โ”‚   โ”œโ”€โ”€ translations.i18n.json      # default ๋ฒˆ์—ญ (์˜์–ด)
โ”‚       โ”‚   โ”œโ”€โ”€ translations_ar.i18n.json   # ์•„๋ž์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_de.i18n.json   # ๋…์ผ์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_es.i18n.json   # ์ŠคํŽ˜์ธ์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_fr.i18n.json   # ํ”„๋ž‘์Šค์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_it.i18n.json   # ์ดํƒˆ๋ฆฌ์•„์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_ja.i18n.json   # ์ผ๋ณธ์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_ko.i18n.json   # ํ•œ๊ตญ์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_pt.i18n.json   # ํฌ๋ฅดํˆฌ๊ฐˆ์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_ru.i18n.json   # ๋Ÿฌ์‹œ์•„์–ด
โ”‚       โ”‚   โ”œโ”€โ”€ translations_zh_Hans.i18n.json  # in progress๊ตญ์–ด ๊ฐ„์ฒด
โ”‚       โ”‚   โ””โ”€โ”€ translations.g.dart         # ์ž๋™ ์ƒ์„ฑ
โ”‚       โ””โ”€โ”€ utils/
โ”‚           โ””โ”€โ”€ translation_extension.dart  # context.i10n ํ™•์žฅ
โ””โ”€โ”€ slang.yaml                              # Slang ์„ค์ •

Import Order (Required)#

// 1. Flutter standard
import 'package:flutter/widgets.dart';

// 2. Slang package
import 'package:slang_flutter/slang_flutter.dart';

// 3. Generated translations
import '../translations/translations.g.dart';

Core Patterns#

1. Main Export File#

/// i10n ํŒจํ‚ค์ง€ export
library i10n;

export 'package:flutter_localizations/flutter_localizations.dart';
export 'package:slang_flutter/slang_flutter.dart';
export 'src/translations/translations.g.dart';
export 'src/utils/translation_extension.dart';

2. context.i10n Extension Method#

import 'package:flutter/widgets.dart';

import '../translations/translations.g.dart';

/// BuildContext ๋ฒˆ์—ญ ํ™•์žฅ
extension TranslationExtension on BuildContext {
  /// ํ˜„์žฌ ๋กœ์ผ€์ผ์˜ ๋ฒˆ์—ญ ๊ฐ์ฒด ์ ‘๊ทผ
  ///
  /// Usage example:
  /// ```dart
  /// Text(context.i10n.home.title)
  /// Text(context.i10n.common.confirm)
  /// <pre><code>  Translations get i10n =&gt; Translations.of(this);
}</code></pre>

### 3. Translation JSON Structure

<pre><code>// translations_ko.i18n.json (ํ•œ๊ตญ์–ด)
{
  &quot;@@locale&quot;: &quot;ko&quot;,
  &quot;common&quot;: {
    &quot;confirm&quot;: &quot;ํ™•์ธ&quot;,
    &quot;cancel&quot;: &quot;์ทจ์†Œ&quot;,
    &quot;save&quot;: &quot;์ €์žฅ&quot;,
    &quot;delete&quot;: &quot;์‚ญ์ œ&quot;,
    &quot;edit&quot;: &quot;์ˆ˜์ •&quot;,
    &quot;close&quot;: &quot;๋‹ซ๊ธฐ&quot;,
    &quot;loading&quot;: &quot;๋กœ๋”ฉ in progress...&quot;,
    &quot;error&quot;: &quot;์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค&quot;,
    &quot;retry&quot;: &quot;๋‹ค์‹œ ์‹œ๋„&quot;,
    &quot;search&quot;: &quot;๊ฒ€์ƒ‰&quot;,
    &quot;noData&quot;: &quot;๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค&quot;
  },
  &quot;auth&quot;: {
    &quot;login&quot;: &quot;๋กœ๊ทธ์ธ&quot;,
    &quot;logout&quot;: &quot;๋กœ๊ทธ์•„์›ƒ&quot;,
    &quot;signUp&quot;: &quot;ํšŒ์›๊ฐ€์ž…&quot;,
    &quot;email&quot;: &quot;์ด๋ฉ”์ผ&quot;,
    &quot;password&quot;: &quot;๋น„๋ฐ€๋ฒˆํ˜ธ&quot;,
    &quot;forgotPassword&quot;: &quot;๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ&quot;
  },
  &quot;home&quot;: {
    &quot;title&quot;: &quot;ํ™ˆ&quot;,
    &quot;welcome&quot;: &quot;ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค, {name}๋‹˜!&quot;,
    &quot;itemCount(context=count)&quot;: {
      &quot;zero&quot;: &quot;ํ•ญ๋ชฉ์ด ์—†์Šต๋‹ˆ๋‹ค&quot;,
      &quot;one&quot;: &quot;1๊ฐœ์˜ ํ•ญ๋ชฉ&quot;,
      &quot;other&quot;: &quot;{count}๊ฐœ์˜ ํ•ญ๋ชฉ&quot;
    }
  },
  &quot;error&quot;: {
    &quot;network&quot;: &quot;๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”&quot;,
    &quot;server&quot;: &quot;์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค&quot;,
    &quot;unknown&quot;: &quot;์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค&quot;,
    &quot;validation&quot;: {
      &quot;required&quot;: &quot;{field}์€(๋Š”) ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค&quot;,
      &quot;email&quot;: &quot;์˜ฌ๋ฐ”๋ฅธ ์ด๋ฉ”์ผ ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค&quot;,
      &quot;minLength&quot;: &quot;{field}์€(๋Š”) ์ตœ์†Œ {min}์ž ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค&quot;
    }
  }
}</code></pre>

### 4. English Translation (Default)

<pre><code>// translations.i18n.json (์˜์–ด - default)
{
  &quot;@@locale&quot;: &quot;en&quot;,
  &quot;common&quot;: {
    &quot;confirm&quot;: &quot;Confirm&quot;,
    &quot;cancel&quot;: &quot;Cancel&quot;,
    &quot;save&quot;: &quot;Save&quot;,
    &quot;delete&quot;: &quot;Delete&quot;,
    &quot;edit&quot;: &quot;Edit&quot;,
    &quot;close&quot;: &quot;Close&quot;,
    &quot;loading&quot;: &quot;Loading...&quot;,
    &quot;error&quot;: &quot;An error occurred&quot;,
    &quot;retry&quot;: &quot;Retry&quot;,
    &quot;search&quot;: &quot;Search&quot;,
    &quot;noData&quot;: &quot;No data available&quot;
  },
  &quot;auth&quot;: {
    &quot;login&quot;: &quot;Login&quot;,
    &quot;logout&quot;: &quot;Logout&quot;,
    &quot;signUp&quot;: &quot;Sign Up&quot;,
    &quot;email&quot;: &quot;Email&quot;,
    &quot;password&quot;: &quot;Password&quot;,
    &quot;forgotPassword&quot;: &quot;Forgot Password&quot;
  },
  &quot;home&quot;: {
    &quot;title&quot;: &quot;Home&quot;,
    &quot;welcome&quot;: &quot;Welcome, {name}!&quot;,
    &quot;itemCount(context=count)&quot;: {
      &quot;zero&quot;: &quot;No items&quot;,
      &quot;one&quot;: &quot;1 item&quot;,
      &quot;other&quot;: &quot;{count} items&quot;
    }
  },
  &quot;error&quot;: {
    &quot;network&quot;: &quot;Please check your network connection&quot;,
    &quot;server&quot;: &quot;A server error occurred&quot;,
    &quot;unknown&quot;: &quot;An unknown error occurred&quot;,
    &quot;validation&quot;: {
      &quot;required&quot;: &quot;{field} is required&quot;,
      &quot;email&quot;: &quot;Invalid email format&quot;,
      &quot;minLength&quot;: &quot;{field} must be at least {min} characters&quot;
    }
  }
}</code></pre>

### 5. Slang Configuration File

<pre><code># slang.yaml
base_locale: en
fallback_strategy: base_locale
input_directory: lib/src/translations
input_file_pattern: .i18n.json
output_directory: lib/src/translations
output_file_name: translations.g.dart
output_format: single_file
key_case: camel
key_map_case: camel
param_case: camel
string_interpolation: braces
flat_map: false
timestamp: false
statistics: true
translation_class_visibility: public
key_class_visibility: public</code></pre>

### 6. Usage in Widget

```dart
import 'package:flutter/material.dart';
import 'package:i10n/i10n.dart';

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(context.i10n.home.title),
      ),
      body: Column(
        children: [
          // ๋‹จ์ˆœ ๋ฌธ์ž์—ด
          Text(context.i10n.common.confirm),

          // ํŒŒ๋ผ๋ฏธํ„ฐ ํฌํ•จ
          Text(context.i10n.home.welcome(name: 'ํ™๊ธธ๋™')),

          // ๋ณต์ˆ˜ํ˜•
          Text(context.i10n.home.itemCount(count: 5)),

          // in progress์ฒฉ ํ‚ค
          Text(context.i10n.error.validation.required(field: '์ด๋ฆ„')),
        ],
      ),
    );
  }
}

7. App Setup#

import 'package:flutter/material.dart';
import 'package:i10n/i10n.dart';

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return TranslationProvider(
      child: MaterialApp(
        locale: TranslationProvider.of(context).flutterLocale,
        supportedLocales: AppLocaleUtils.supportedLocales,
        localizationsDelegates: GlobalMaterialLocalizations.delegates,
        home: const HomePage(),
      ),
    );
  }
}

Translation Grammar#

Basic String#

{
   " greeting " :  " ์•ˆ๋…•ํ•˜์„ธ์š” " 
 }

Usage: context.i10n.greeting

Parameters#

{
   " welcome " :  " ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค, {name}๋‹˜! " 
 }

Usage: context.i10n.welcome(name: 'ํ™๊ธธ๋™')

Plurals#

{
   " itemCount(context=count) " : {
     " zero " :  " ํ•ญ๋ชฉ ์—†์Œ " ,
     " one " :  " 1๊ฐœ ํ•ญ๋ชฉ " ,
     " two " :  " 2๊ฐœ ํ•ญ๋ชฉ " ,
     " few " :  " {count}๊ฐœ ํ•ญ๋ชฉ " ,
     " many " :  " {count}๊ฐœ ํ•ญ๋ชฉ " ,
     " other " :  " {count}๊ฐœ ํ•ญ๋ชฉ " 
   }
}

Usage: context.i10n.itemCount(count: 5)

Gender#

{
   " greetPerson(context=gender) " : {
     " male " :  " {name}์”จ " ,
     " female " :  " {name}๋‹˜ " ,
     " other " :  " {name}๋‹˜ " 
   }
}

Usage: context.i10n.greetPerson(gender: Gender.female, name: '๊น€์˜ํฌ')

Nested Keys#

{
   " error " : {
     " validation " : {
       " required " :  " {field}์€(๋Š”) ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค " 
     }
  }
}

Usage: context.i10n.error.validation.required(field: '์ด๋ฉ”์ผ')


Build Commands#

# Generate translation code
melos run generate:locale

# Verify translation files
melos run translate:slang:fix

# Translate all languages (using AI)
melos run translate:slang:all

# Build specific package only
cd shared/i10n  & &   dart run build_runner build --delete-conflicting-outputs

Reference Files#

shared/i10n/lib/i10n.dart
shared/i10n/lib/src/utils/translation_extension.dart
shared/i10n/lib/src/translations/translations_ko.i18n.json
shared/i10n/slang.yaml

Checklist#

  • Write translations.i18n.json (English) default translation
  • Write translations_ko.i18n.json (Korean) translation
  • Verify parameter syntax {param} is correct
  • Verify plural context=count syntax
  • Verify slang.yaml configuration
  • Execute melos run generate:locale
  • Verify context.i10n extension method usage
  • Place TranslationProvider at app root