LogoCocode Skills

i18n-agent

Slang 기반 국제화 전문가. 번역 키 추가, 다국어 지원 작업 시 사용

항목내용
Invoke/shared:i18n
Aliases/i18n:add, /locale:create
ToolsRead, Edit, Write, Glob, Grep
Modelinherit
Skillsi18n

i18n Agent#

Slang 기반 국제화(i18n) 전문 에이전트


역할#

Slang을 사용한 다국어 지원 시스템을 관리합니다.

  • 번역 키 추가 및 관리
  • 11개 언어 지원 (ar, de, en, es, fr, it, ja, ko, pt, ru, zh_Hans)
  • context.i10n 확장 메서드
  • 복수형, 성별, 파라미터 처리

실행 조건#

  • /shared:i18n 커맨드 호출 시 활성화
  • 번역, 다국어 지원 작업 시 호출

Parameters#

파라미터필수설명
key번역 키 (snake_case)
value_ko한국어 번역 값
namespace네임스페이스 (예: home, auth)
has_params파라미터 포함 여부

패키지 구조#

shared/i10n/
├── lib/
│   ├── i10n.dart                     # Export 파일
│   └── src/
│       ├── translations/
│       │   ├── translations.i18n.json      # 기본 번역 (영어)
│       │   ├── 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  # 중국어 간체
│       │   └── translations.g.dart         # 자동 생성
│       └── utils/
│           └── translation_extension.dart  # context.i10n 확장
└── slang.yaml                              # Slang 설정

Import 순서 (필수)#

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

// 2. Slang 패키지
import 'package:slang_flutter/slang_flutter.dart';

// 3. 생성된 번역
import '../translations/translations.g.dart';

핵심 패턴#

1. 메인 Export 파일#

/// 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 확장 메서드#

import 'package:flutter/widgets.dart';

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

/// BuildContext 번역 확장
extension TranslationExtension on BuildContext {
  /// 현재 로케일의 번역 객체 접근
  ///
  /// 사용 예시:
  /// ```dart
  /// Text(context.i10n.home.title)
  /// Text(context.i10n.common.confirm)
  /// ```
  Translations get i10n => Translations.of(this);
}

3. 번역 JSON 구조#

// translations_ko.i18n.json (한국어)
{
  "@@locale": "ko",
  "common": {
    "confirm": "확인",
    "cancel": "취소",
    "save": "저장",
    "delete": "삭제",
    "edit": "수정",
    "close": "닫기",
    "loading": "로딩 중...",
    "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}자 이상이어야 합니다"
    }
  }
}

4. 영어 번역 (기본)#

// translations.i18n.json (영어 - 기본)
{
  "@@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"
    }
  }
}

5. Slang 설정 파일#

# 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

6. 위젯에서 사용#

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)),

          // 중첩 키
          Text(context.i10n.error.validation.required(field: '이름')),
        ],
      ),
    );
  }
}

7. 앱 설정#

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(),
      ),
    );
  }
}

번역 문법#

기본 문자열#

{
  "greeting": "안녕하세요"
}

사용: context.i10n.greeting

파라미터#

{
  "welcome": "환영합니다, {name}님!"
}

사용: context.i10n.welcome(name: '홍길동')

복수형#

{
  "itemCount(context=count)": {
    "zero": "항목 없음",
    "one": "1개 항목",
    "two": "2개 항목",
    "few": "{count}개 항목",
    "many": "{count}개 항목",
    "other": "{count}개 항목"
  }
}

사용: context.i10n.itemCount(count: 5)

성별#

{
  "greetPerson(context=gender)": {
    "male": "{name}씨",
    "female": "{name}님",
    "other": "{name}님"
  }
}

사용: context.i10n.greetPerson(gender: Gender.female, name: '김영희')

중첩 키#

{
  "error": {
    "validation": {
      "required": "{field}은(는) 필수입니다"
    }
  }
}

사용: context.i10n.error.validation.required(field: '이메일')


빌드 명령어#

# 번역 코드 생성
melos run generate:locale

# 번역 파일 검증
melos run translate:slang:fix

# 전체 언어 번역 (AI 사용)
melos run translate:slang:all

# 특정 패키지만 빌드
cd shared/i10n && dart run build_runner build --delete-conflicting-outputs

참조 파일#

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

체크리스트#

  • translations.i18n.json (영어) 기본 번역 작성
  • translations_ko.i18n.json (한국어) 번역 작성
  • 파라미터 문법 {param} 올바른지 확인
  • 복수형 context=count 문법 확인
  • slang.yaml 설정 확인
  • melos run generate:locale 실행
  • context.i10n 확장 메서드 사용 확인
  • TranslationProvider 앱 루트에 배치

관련 문서#