| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| Invoke | /shared:i18n |
| Aliases | /i18n:add, /locale:create |
| Tools | Read, Edit, Write, Glob, Grep |
| Model | sonnet |
| Skills | i18n |
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:i18nActivated when command is invoked- Invoked during translation and multi-language support work
Parameters#
| Parameter | Required | Description |
|---|---|---|
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 => Translations.of(this);
}</code></pre>
### 3. Translation JSON Structure
<pre><code>// translations_ko.i18n.json (ํ๊ตญ์ด)
{
"@@locale": "ko",
"common": {
"confirm": "ํ์ธ",
"cancel": "์ทจ์",
"save": "์ ์ฅ",
"delete": "์ญ์ ",
"edit": "์์ ",
"close": "๋ซ๊ธฐ",
"loading": "๋ก๋ฉ in progress...",
"error": "์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค",
"retry": "๋ค์ ์๋",
"search": "๊ฒ์",
"noData": "๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค"
},
"auth": {
"login": "๋ก๊ทธ์ธ",
"logout": "๋ก๊ทธ์์",
"signUp": "ํ์๊ฐ์
",
"email": "์ด๋ฉ์ผ",
"password": "๋น๋ฐ๋ฒํธ",
"forgotPassword": "๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ"
},
"home": {
"title": "ํ",
"welcome": "ํ์ํฉ๋๋ค, {name}๋!",
"itemCount(context=count)": {
"zero": "ํญ๋ชฉ์ด ์์ต๋๋ค",
"one": "1๊ฐ์ ํญ๋ชฉ",
"other": "{count}๊ฐ์ ํญ๋ชฉ"
}
},
"error": {
"network": "๋คํธ์ํฌ ์ฐ๊ฒฐ์ ํ์ธํด์ฃผ์ธ์",
"server": "์๋ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค",
"unknown": "์ ์ ์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค",
"validation": {
"required": "{field}์(๋) ํ์์
๋๋ค",
"email": "์ฌ๋ฐ๋ฅธ ์ด๋ฉ์ผ ํ์์ด ์๋๋๋ค",
"minLength": "{field}์(๋) ์ต์ {min}์ ์ด์์ด์ด์ผ ํฉ๋๋ค"
}
}
}</code></pre>
### 4. English Translation (Default)
<pre><code>// translations.i18n.json (์์ด - default)
{
"@@locale": "en",
"common": {
"confirm": "Confirm",
"cancel": "Cancel",
"save": "Save",
"delete": "Delete",
"edit": "Edit",
"close": "Close",
"loading": "Loading...",
"error": "An error occurred",
"retry": "Retry",
"search": "Search",
"noData": "No data available"
},
"auth": {
"login": "Login",
"logout": "Logout",
"signUp": "Sign Up",
"email": "Email",
"password": "Password",
"forgotPassword": "Forgot Password"
},
"home": {
"title": "Home",
"welcome": "Welcome, {name}!",
"itemCount(context=count)": {
"zero": "No items",
"one": "1 item",
"other": "{count} items"
}
},
"error": {
"network": "Please check your network connection",
"server": "A server error occurred",
"unknown": "An unknown error occurred",
"validation": {
"required": "{field} is required",
"email": "Invalid email format",
"minLength": "{field} must be at least {min} characters"
}
}
}</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