[{"data":1,"prerenderedAt":27},["ShallowReactive",2],{"articolo-localizzare-rapidamente-le-app-flutter-con-slang-type-safe-i18n-senza-intl":3,"comments-article-localizzare-rapidamente-le-app-flutter-con-slang-type-safe-i18n-senza-intl":26},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"cover_remote_url":10,"cover_credit":11,"video_url":15,"status":16,"published_at":17,"meta_title":18,"meta_description":19,"category":20,"author":24},62,"Localizzare rapidamente le app Flutter con slang: type-safe i18n senza intl","localizzare-rapidamente-le-app-flutter-con-slang-type-safe-i18n-senza-intl","Scopri slang, il package che genera traduzioni type-safe da file JSON o YAML, con autocompletamento, pluralizzazione e interpolazione, come alternativa moderna a intl.","## Introduzione\n\nLa localizzazione è un aspetto fondamentale per qualsiasi app che punti a un pubblico internazionale. In Flutter l'approccio ufficiale con `flutter_localizations` e `intl` è potente ma verboso: file ARB, generazione di codice, chiavi accessibili tramite metodi lunghi e nessun autocompletamento immediato sulle stringhe annidate.\n\nIn questo articolo vediamo **slang**, un package che offre una localizzazione **type-safe**, con autocompletamento completo, supporto a pluralizzazione, interpolazione e namespace, partendo da semplici file JSON o YAML.\n\n## Perché slang\n\n- **Type-safe**: le traduzioni sono accessibili tramite oggetti generati, niente stringhe magiche.\n- **Autocompletamento**: l'IDE suggerisce tutte le chiavi disponibili.\n- **Struttura annidata**: puoi organizzare le traduzioni in modo gerarchico.\n- **Nessuna dipendenza da context** (opzionale): puoi tradurre anche fuori dal widget tree.\n- **Pluralizzazione e genere** integrati.\n\n## Installazione\n\nAggiungi le dipendenze al `pubspec.yaml`:\n\n```yaml\ndependencies:\n  slang: ^3.31.0\n  slang_flutter: ^3.31.0\n\ndev_dependencies:\n  slang_build_runner: ^3.31.0\n  build_runner: ^2.4.0\n```\n\n## Creare i file di traduzione\n\nCrea una cartella `lib\u002Fi18n` con un file per ogni lingua. Il file base è quello senza suffisso di locale.\n\n**`lib\u002Fi18n\u002Fstrings.i18n.json`** (italiano, lingua base):\n\n```json\n{\n  \"home\": {\n    \"title\": \"Benvenuto\",\n    \"greeting\": \"Ciao $name!\",\n    \"itemCount\": {\n      \"one\": \"$n elemento\",\n      \"other\": \"$n elementi\"\n    }\n  },\n  \"login\": {\n    \"button\": \"Accedi\"\n  }\n}\n```\n\n**`lib\u002Fi18n\u002Fstrings_en.i18n.json`** (inglese):\n\n```json\n{\n  \"home\": {\n    \"title\": \"Welcome\",\n    \"greeting\": \"Hi $name!\",\n    \"itemCount\": {\n      \"one\": \"$n item\",\n      \"other\": \"$n items\"\n    }\n  },\n  \"login\": {\n    \"button\": \"Sign in\"\n  }\n}\n```\n\n## Generare il codice\n\nEsegui il generatore:\n\n```bash\ndart run slang\n```\n\nOppure con build_runner in modalità watch:\n\n```bash\ndart run build_runner watch\n```\n\nVerrà creato il file `strings.g.dart` con tutte le classi type-safe.\n\n## Configurare l'app\n\nAvvolgi la tua app con `TranslationProvider`:\n\n```dart\nimport 'package:flutter\u002Fmaterial.dart';\nimport 'i18n\u002Fstrings.g.dart';\n\nvoid main() {\n  WidgetsFlutterBinding.ensureInitialized();\n  \u002F\u002F Imposta la lingua in base al dispositivo\n  LocaleSettings.useDeviceLocale();\n  runApp(TranslationProvider(child: const MyApp()));\n}\n```\n\nCollega i delegate di Flutter per il supporto completo:\n\n```dart\nMaterialApp(\n  locale: TranslationProvider.of(context).flutterLocale,\n  supportedLocales: AppLocaleUtils.supportedLocales,\n  localizationsDelegates: GlobalMaterialLocalizations.delegates,\n  home: const HomePage(),\n)\n```\n\n## Usare le traduzioni\n\nAccedi alle stringhe tramite l'oggetto `t`, con autocompletamento completo:\n\n```dart\nclass HomePage extends StatelessWidget {\n  const HomePage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: Text(t.home.title)),\n      body: Column(\n        children: [\n          Text(t.home.greeting(name: 'Marco')),\n          Text(t.home.itemCount(n: 3)), \u002F\u002F -> \"3 elementi\"\n          ElevatedButton(\n            onPressed: () {},\n            child: Text(t.login.button),\n          ),\n        ],\n      ),\n    );\n  }\n}\n```\n\nNota come l'interpolazione (`name`) e la pluralizzazione (`n`) siano parametri tipizzati: l'IDE ti segnala subito eventuali errori.\n\n## Cambiare lingua a runtime\n\n```dart\n\u002F\u002F Cambia lingua e ricostruisce i widget sotto TranslationProvider\nLocaleSettings.setLocale(AppLocale.en);\n\n\u002F\u002F Oppure con codice locale\nLocaleSettings.setLocaleRaw('it');\n```\n\nSe usi `context`, puoi ottenere le traduzioni reattive con:\n\n```dart\nfinal t = Translations.of(context);\n```\n\nIn questo modo i widget si aggiornano automaticamente al cambio di lingua.\n\n## Namespace per file multipli\n\nPer progetti grandi puoi suddividere le traduzioni in più file abilitando i namespace nel `build.yaml`:\n\n```yaml\ntargets:\n  $default:\n    builders:\n      slang_build_runner:\n        options:\n          namespaces: true\n```\n\nAvrai file come `home.i18n.json`, `login.i18n.json` e li accederai con `t.home.title`, `t.login.button`.\n\n## slang vs intl\n\n| Caratteristica | slang | intl\u002FARB |\n|---|---|---|\n| Type-safe | Sì, nativo | Parziale |\n| Autocompletamento annidato | Ottimo | Limitato |\n| Formato file | JSON\u002FYAML\u002FCSV | ARB |\n| Traduzione fuori dal context | Sì | No |\n| Standard ufficiale | No | Sì |\n\n## Conclusione\n\nslang è un'alternativa moderna e produttiva per la localizzazione in Flutter. Se non hai vincoli sull'uso dello standard ARB, offre un'esperienza di sviluppo più fluida grazie all'autocompletamento e alla sicurezza dei tipi. Per progetti che devono integrarsi con flussi di traduzione basati su ARB, `intl` resta la scelta più conservativa, ma per la maggior parte delle app slang riduce sensibilmente il codice ripetitivo e gli errori.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002Fe36b61a1-e28e-413a-92c0-7a9d298765f4.jpg","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1783282462007-0a66f07fd06a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w5NzA2NTJ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3ODczMTU4MzF8&ixlib=rb-4.1.0&q=80&w=1080",{"name":12,"author_url":13,"photo_url":14},"David Heilbron","https:\u002F\u002Funsplash.com\u002F@heilbron","https:\u002F\u002Funsplash.com\u002Fphotos\u002Fnational-flags-adorn-a-building-with-mountains-in-the-background-R1R4VS9UpxE",null,"published","2026-08-10T04:00:39+00:00","Localizzazione Flutter con slang: i18n type-safe","Guida a slang per Flutter: traduzioni type-safe da JSON\u002FYAML con autocompletamento, pluralizzazione e cambio lingua a runtime, alternativa a intl.",{"id":21,"name":22,"slug":23},1,"Guide","guide",{"id":21,"name":25},"Flutter Bot",[],1789120588441]