Guides 15 min de lecture

Localizable.strings sur iOS : format, exemples et migration vers les String Catalogs (2026)

Guide pratique du fichier Localizable.strings sur iOS : la syntaxe exacte "clé" = "valeur";, commentaires et échappements, dossiers .lproj et Base, recherche des chaînes avec NSLocalizedString, String(localized:) et Text, un .stringsdict minimal, erreurs fréquentes, plutil -lint et migration pas à pas vers les String Catalogs.

Sommaire14 parties

Localizable.strings est le fichier iOS classique qui contient les traductions d’une app : un fichier par langue, dans un dossier comme en.lproj ou fr.lproj, fait de lignes comme "Settings" = "Réglages";. Le code y cherche ses clés avec NSLocalizedString, String(localized:) ou le Text de SwiftUI, et par défaut, quand une clé manque, l’utilisateur voit la clé elle-même. Le format fonctionne toujours en 2026, mais Apple présente les catalogues de chaînes (String Catalogs, .xcstrings, Xcode 15 et ultérieur) comme son remplaçant, et Xcode sait migrer un fichier .strings en quelques clics. Ce guide détaille la syntaxe exacte, l’emplacement des fichiers, la recherche des traductions, les erreurs qui cassent un fichier, sa validation avec plutil -lint et la migration.

Points clés

  • Chaque entrée s’écrit "clé" = "valeur";, avec un point-virgule final ; guillemets et barres obliques inverses se protègent par une barre oblique inverse.
  • Une seule erreur de syntaxe peut rendre illisible toute la table d’une langue : chaque chaîne de cette langue affiche alors sa clé.
  • Enregistrez les fichiers sources en UTF-8 ; Xcode les convertit dans l’app compilée (en UTF-16 par défaut).
  • Passez plutil -lint sur chaque fichier .strings avant de compiler ou de migrer.
  • Pour tout nouveau travail, utilisez un catalogue de chaînes ; les fichiers existants se migrent table par table avec Migrate to String Catalog (Xcode 15 ou ultérieur).

Qu’est-ce que Localizable.strings ?

Un fichier de chaînes est une liste de paires clé-valeur : la clé est ce que demande le code, la valeur le texte affiché dans une langue. Le guide String Resources d’Apple (en anglais) nomme le fichier par défaut : « The name of the default strings file is Localizable.strings but you can create strings files with any file name you choose. » Chaque fichier forme une table, dont le nom est celui du fichier sans .strings : Localizable par défaut, Settings pour Settings.strings.

Les pluriels exigent un fichier .stringsdict complémentaire (voir plus bas) ; un catalogue de chaînes réunit les deux, pour toutes les langues, dans un seul fichier. Pour l’ensemble du processus, consultez notre guide de la localisation iOS.

Syntaxe : clés, valeurs, commentaires et échappements

Les règles d’Apple sont brèves : clé et valeur sont placées entre guillemets droits et séparées par un signe égal, l’entrée entière se termine par un point-virgule, et les commentaires s’écrivent entre délimiteurs de style C (/* et */), juste avant l’entrée qu’ils décrivent. Un fichier français complet ressemble à ceci :

/* fr.lproj/Localizable.strings */

/* Titre de l'onglet qui liste les éléments enregistrés */
"Saved" = "Enregistrés";

/* Clé explicite : le mot anglais peut changer sans casser les traductions */
"settings.title" = "Réglages";

/* %@ est le prénom de l'utilisateur */
"Welcome back, %@!" = "Bon retour, %@ !";

/* Les arguments positionnels permettent de réordonner les valeurs */
"%1$@ shared %2$lld photos" = "%2$lld photos partagées par %1$@";

/* Guillemets échappés et retour à la ligne */
"file.not.found" = "Le fichier \"%@\" est introuvable.\nVérifiez son nom.";
Pour écrireTapezExemple
Un guillemet dans une chaîne\""Ouvrir \"%@\" ?"
Une barre oblique inverse\\"C:\\Users"
Un retour à la ligne\n"Ligne 1\nLigne 2"
Un retour chariot\rRarement utile sur les plateformes Apple
N’importe quel caractère Unicode\U + jusqu’à quatre chiffres hexadécimaux"\U202F" (espace fine insécable)
Un signe pour cent dans une chaîne de format%%"%lld %% terminé"
Séquences d’échappement d’un fichier de chaînes (guide String Resources d’Apple ; %% suit la règle de printf)

La clé doit correspondre caractère pour caractère à ce que demande le code, spécificateurs de format compris. L’interpolation Swift d’un Int, comme dans String(localized: "\(count) photos"), produit la clé "%lld photos" et non "%d photos" ; un String produit %@. Apple accepte aussi des fichiers de chaînes au format liste de propriétés, mais le format entre guillemets ci-dessus reste l’usage.

Où vit le fichier : en.lproj, fr.lproj et Base.lproj

Une ressource localisée vit dans un dossier par langue, nommé d’après l’identifiant de langue avec l’extension .lproj : en.lproj, fr.lproj, pt-BR.lproj. Chaque dossier a son propre Localizable.strings, avec les mêmes clés et des valeurs traduites. À côté se trouvent parfois Localizable.stringsdict pour les pluriels et InfoPlist.strings pour les clés localisées d’Info.plist, comme le nom affiché et les textes d’autorisation.

Base.lproj est un cas à part : le guide d’internationalisation d’Apple en fait le dossier des storyboards et des XIB dans la langue de développement (« base internationalization »), pour lesquels des fichiers de chaînes sont générés par langue. Les chaînes utilisées dans le code vont dans Localizable.strings.

Arborescence d'un projet iOS fictif : Base.lproj contient Main.storyboard, et en.lproj, fr.lproj et de.lproj contiennent chacun Localizable.strings, Localizable.stringsdict et InfoPlist.strings ; à droite, une même entrée française dans le fichier source et la règle selon laquelle le nom de table est le nom du fichier sans .strings
Illustration : où se placent les fichiers de chaînes dans un projet, et comment les noms de fichiers deviennent des noms de tables (schéma simplifié, pas une capture de Xcode).

InfoPlist.strings : le nom de l’app et les demandes d’autorisation

InfoPlist.strings traduit les clés de Info.plist visibles par l’utilisateur, que Localizable.strings ne peut pas atteindre. Il utilise la même syntaxe "clé" = "valeur"; et vit dans les mêmes dossiers .lproj, mais ses clés sont les noms bruts des clés de Info.plist. La valeur écrite dans Info.plist reste la valeur de repli pour la langue de développement.

/* fr.lproj/InfoPlist.strings */

/* Nom sous l'icône sur l'écran d'accueil */
"CFBundleDisplayName" = "Mon Carnet";

/* Demande d'accès à l'appareil photo */
"NSCameraUsageDescription" = "L’appareil photo sert à scanner l’étiquette d’un produit.";
  • Nom de l’app : CFBundleDisplayName est le nom affiché sous l’icône. Le nom sur l’App Store est distinct et se règle langue par langue dans App Store Connect.
  • Demandes d’autorisation : chaque clé NS…UsageDescription, comme l’appareil photo, le micro, la localisation ou Santé, affichée dans l’alerte système qui demande l’accès.
  • Le créer : ajoutez un fichier Strings nommé InfoPlist, cliquez sur Localize dans l’inspecteur de fichier et cochez chaque langue.
  • Avec les String Catalogs : InfoPlist.xcstrings le remplace, et Xcode y ajoute lui-même les clés localisables. Voir InfoPlist.xcstrings dans notre guide de localisation iOS.

Créer un fichier Localizable.strings

Pour un nouveau projet, créez plutôt un catalogue de chaînes (File › New › File from Template › String Catalog). S’il vous faut un fichier classique, par exemple pour rester cohérent avec un projet existant :

  1. Choisissez File › New › File from Template, tapez strings dans le champ de filtre et prenez le modèle de fichier de chaînes (pas String Catalog). Nommez-le Localizable pour qu’il devienne la table par défaut.
  2. Sélectionnez-le dans le navigateur de projet, ouvrez l’inspecteur de fichier et cliquez sur Localize, sous Localization, puis choisissez la langue de développement. L’article d’Apple sur les pluriels décrit les mêmes étapes pour un fichier .stringsdict.
  3. Cochez les autres langues dans le même panneau ; chacune ajoute une copie dans son dossier .lproj. Les langues du projet sont listées dans l’éditeur de projet, onglet Info, rubrique Localizations.
  4. Vérifiez que le fichier appartient à la bonne cible (Target Membership, dans l’inspecteur de fichier) : sinon, il n’arrive jamais dans l’app.

Comment iOS trouve une chaîne : NSLocalizedString, String(localized:) et Text

Chaque API prend une clé, une table et un bundle. La table par défaut est Localizable ; pour lire Settings.strings, passez "Settings".

// SwiftUI : un littéral est une LocalizedStringKey, cherchée dans Localizable.strings
Text("Saved")
Text("settings.title", tableName: "Settings")

// Swift hors des vues (iOS 15 et ultérieur)
let title = String(localized: "settings.title", table: "Settings",
                   comment: "Title of the Settings screen")
let toast = String(localized: "Welcome back, \(name)!")   // clé : "Welcome back, %@!"

// Foundation, toute version d'iOS : value est renvoyée si la clé manque
let saved = NSLocalizedString("Saved", value: "Saved",
                              comment: "Tab title for the list of saved items")

// Dans un package Swift, cherchez les chaînes dans le bundle du package
Text("Saved", bundle: .module)
APIParamètre de tableSi la clé est introuvable
Text(_:tableName:bundle:comment:)tableNameAffiche la clé
String(localized:table:bundle:locale:comment:)tableLa clé sert aussi de valeur par défaut
String(localized:defaultValue:table:…)tableRenvoie defaultValue
NSLocalizedString(_:tableName:bundle:value:comment:)tableNameRenvoie value, ou la clé si value est vide
Bundle.localizedString(forKey:value:table:)tableComme NSLocalizedString
Les API de recherche et leur repli (documentation d’Apple de Text, String, NSLocalizedString et Bundle)

C’est le bundle qui choisit le dossier de langue : preferredLocalizations classe les localisations de l’app selon les préférences de l’utilisateur, et CFBundleDevelopmentRegion sert de langue quand le système ne trouve pas de ressource pour la langue préférée. Une clé absente n’est pas cherchée en anglais : la documentation de localizedString(forKey:value:table:) indique que la méthode renvoie la clé quand elle est introuvable et qu’aucune valeur n’est fournie. Des clés lisibles (« Saved ») se dégradent donc mieux que des clés techniques (« tab.saved »), sauf si vous passez une valeur par défaut.

Schéma de la recherche d'une chaîne : la clé venue de Text, String(localized:) ou NSLocalizedString va vers une table, Localizable par défaut, dans un bundle, principal ou celui du package ; le bundle choisit un dossier de langue d'après les langues préférées de l'utilisateur, avec repli sur la région de développement ; si la clé est trouvée, la traduction s'affiche, sinon la valeur par défaut ou la clé elle-même
Illustration : de la clé au texte affiché, et ce que voit l’utilisateur quand une clé manque (schéma simplifié).

Pluriels : un .stringsdict minimal

Un fichier .strings ne sait pas faire varier une phrase selon une quantité. Localizable.stringsdict, une liste de propriétés placée dans le même dossier .lproj, associe la clé de format à une chaîne par catégorie de pluriel. La plus petite version française utile :

<!-- fr.lproj/Localizable.stringsdict -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>%lld photos</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@photos@</string>
        <key>photos</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>lld</string>
            <key>one</key>
            <string>%lld photo</string>
            <key>other</key>
            <string>%lld photos</string>
        </dict>
    </dict>
</dict>
</plist>
// Swift : l'Int interpolé devient %lld, comme la clé du .stringsdict
Text("\(count) photos")
let label = String(localized: "\(count) photos")

// Foundation : formatez la chaîne trouvée avec le nombre
let format = NSLocalizedString("%lld photos", comment: "Number of photos in an album")
let text = String.localizedStringWithFormat(format, count)

En français, la forme one couvre aussi zéro (« 0 photo »), selon les règles de pluriel Unicode CLDR ; le russe exige one, few, many et other. Les catalogues de chaînes remplacent toute cette liste de propriétés par Vary by Plural sur la clé, comme le détaille notre guide des pluriels dans les catalogues de chaînes.

Erreurs courantes et solutions

SymptômeCause probableSolution
Toutes les chaînes d’une langue affichent leur cléErreur de syntaxe quelque part dans le fichier de cette languePasser plutil -lint et corriger l’entrée en cause
Une chaîne affiche sa cléClé absente de la table, ou écrite autrement dans le codeAjouter la clé ; comparer ponctuation et spécificateurs (%lld, %@)
Les caractères accentués cassent le fichierFichier enregistré dans un ancien encodage comme Latin-1Le réenregistrer en UTF-8
Une traduction est fausse sans prévenirClé en double dans le même fichierRepérer les doublons et n’en garder qu’un
Rien n’est jamais traduitFichier absent de la cible, mauvais nom de table ou mauvais bundleVérifier Target Membership, tableName et bundle
Les problèmes de Localizable.strings en un coup d’œil

Point-virgule manquant ou guillemet non échappé

La casse la plus fréquente : une ligne sans son ; final, un guillemet non échappé dans une valeur, ou des guillemets typographiques (“ ”) collés comme délimiteurs. Le fichier ne peut plus être lu, et toute la table est perdue pour cette langue. Lors de notre test avec un package Swift compilé par Xcode 27.2, un fichier français privé d’un seul point-virgule compilait sans avertissement, et à l’exécution chaque recherche en français renvoyait sa clé. plutil le détecte immédiatement :

$ plutil -lint fr.lproj/Localizable.strings
fr.lproj/Localizable.strings: (Unexpected character " at line 1)

Ne vous fiez pas au numéro de ligne : dans nos tests, il indiquait « line 1 » pour une erreur à la ligne 4. Regardez plutôt la fin de chaque entrée, en commençant par les dernières modifiées.

Encodage : UTF-8 ou UTF-16 ?

Enregistrez le fichier que vous modifiez en UTF-8. Le réglage de compilation Strings File Output Encoding d’Apple indique que l’encodage de sortie est UTF-16 par défaut et que « It is recommended that the source file be in UTF-8 encoding » ; Xcode convertit le fichier à la compilation, et le traitement échoue si la conversion est impossible. L’UTF-16 est donc le format de la copie placée dans l’app compilée, pas un format à produire vous-même. Un fichier enregistré en Latin-1 avec des lettres accentuées échoue à plutil -lint avec le même message « Unexpected character ».

Clés en double

La règle d’Apple : « within a single strings file, each key must be unique ». genstrings signale les doublons, mais pas un fichier modifié à la main : plutil -lint répondait OK sur un fichier contenant deux fois la même clé, et dans notre test à l’exécution, c’est la seconde valeur qui l’emportait. Pour lister les doublons :

grep -o '^"[^"]*"' fr.lproj/Localizable.strings | sort | uniq -d

« Localizable.strings ne fonctionne pas » : la clé s’affiche à la place de la traduction

  1. Passez chaque langue au lint, puis comparez la clé : elle doit correspondre exactement, ponctuation, espaces et spécificateurs de format compris.
  2. Vérifiez la table et le bundle. Un fichier nommé Strings.strings est la table Strings ; le code d’un framework ou d’un package doit chercher dans son propre bundle (.module dans un package Swift), puisque le bundle principal est la valeur par défaut.
  3. Vérifiez Target Membership et Localization dans l’inspecteur de fichier, et que la langue figure dans les Localizations du projet.
  4. Cherchez les variables de type String. Text(label) avec une variable String s’affiche telle quelle ; la documentation de Text propose Text(LocalizedStringKey(label)) pour qu’elle soit cherchée.
  5. Rendez les clés manquantes visibles. Avec le réglage utilisateur (user default) NSShowNonLocalizedStrings réglé sur YES, Apple indique qu’une chaîne introuvable est consignée dans la console et sa clé mise en majuscules. Dans l’éditeur de schéma, Run › Options › « Show non-localized strings » aide à repérer le texte non traduit pendant le débogage.

Valider avec plutil -lint

Le guide String Resources d’Apple le recommande : « Running plutil with the -lint option can uncover hidden characters or other errors that are preventing strings from being retrieved correctly. » Lancez-le sur chaque fichier de chaînes, en local ou en intégration continue :

# Vérifier tous les fichiers .strings du dossier courant
find . -name "*.strings" -exec plutil -lint {} +

# Un fichier valide affiche :
# ./MyApp/fr.lproj/Localizable.strings: OK

# Compter les entrées d'une langue, pour comparer avec une autre
plutil -convert json -o - fr.lproj/Localizable.strings | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))'

plutil vérifie seulement que le fichier se lit : il ne signale ni les clés en double, ni les traductions manquantes, ni les placeholders incohérents.

Garder Localizable.strings ou migrer ?

Dans sa session Discover String Catalogs (WWDC23), Apple annonce que ce nouveau format remplacera à terme les fichiers strings et stringsdict, que les catalogues sont compilés en .strings et .stringsdict, sans changer la version minimale d’iOS, et qu’ils cohabitent avec les anciens formats. Xcode n’est pas non plus une raison d’attendre : depuis le 28 avril 2026, les builds envoyés sur l’App Store doivent être compilés avec Xcode 26 ou ultérieur (page Upcoming Requirements d’Apple).

Votre situationRecommandation
Nouvelle app ou nouvelle tableCatalogue de chaînes dès le départ
App existante en développement actifMigrer d’abord Localizable, les autres tables ensuite
Gel de version ou grosse branche en coursGarder les fichiers pour l’instant et migrer après la fusion, en un seul diff
Un outil de traduction qui ne lit que les .stringsVérifier s’il accepte les .xcstrings ou le XLIFF d’Export Localizations ; garder les fichiers en attendant
Pluriels ou textes par appareil tenus à la mainMigrer : Vary by Plural et Vary by Device remplacent le .stringsdict
Quand garder Localizable.strings, et quand passer à un catalogue de chaînes

Migrer Localizable.strings vers un catalogue de chaînes, pas à pas

  1. Commencez par le lint. Passez plutil -lint sur chaque langue et corrigez les erreurs, pour que toutes les traductions puissent être lues. Notez le nombre d’entrées par langue.
  2. Faites un commit ou une branche, pour relire ou annuler la migration en un seul diff.
  3. Faites un clic droit (ou Contrôle-clic) sur Localizable.strings dans le navigateur de projet et choisissez Migrate to String Catalog, avec Xcode 15 ou ultérieur.
  4. Choisissez les tables. Dans la démonstration d’Apple à la WWDC23, l’assistant de migration liste tous les fichiers migrables, par cible ; cochez Localizable, et les autres tables quand vous serez prêt.
  5. Laissez Xcode compiler. Il compile pour extraire les chaînes ; dans la démonstration d’Apple, toutes les chaînes du fichier strings, et même les pluriels du fichier stringsdict, arrivent dans Localizable.xcstrings.
  6. Comparez les nombres. Le nombre de clés du catalogue doit correspondre au nombre d’entrées de la langue source noté à l’étape 1 :
    python3 -c 'import json; print(len(json.load(open("Localizable.xcstrings"))["strings"]))'
  7. Faites le ménage. Ne laissez aucun fichier .strings ou .stringsdict portant le même nom de table dans un dossier .lproj, puis lancez l’app dans chaque langue.

Votre code ne change pas, puisque la table s’appelle toujours Localizable. La checklist complète, avec le réglage de compilation à vérifier, se trouve dans la section Localizable.strings ou String Catalogs de notre guide de la localisation.

Après la migration : traduire le catalogue

Une fois vos chaînes dans un fichier .xcstrings, notre app Mac Xlocalize le traduit directement avec OpenAI, Anthropic Claude ou Google Gemini, avec votre propre clé d’API stockée dans le trousseau macOS. Elle préserve pluriels, variantes par appareil et substitutions, et signale les placeholders incohérents et les traductions manquantes. Elle travaille sur les catalogues de chaînes, pas sur les fichiers .strings : une raison de plus de migrer d’abord. Elle fonctionne sous macOS 14 ou ultérieur et se télécharge gratuitement, avec des achats intégrés facultatifs.

Pour confier tout le travail, de la migration à la relecture sur appareil et à la fiche App Store localisée, découvrez notre service de localisation d’application.

Questions fréquentes

Qu’est-ce que le fichier Localizable.strings ?

Le fichier de chaînes par défaut d’une app iOS ou macOS : des entrées "clé" = "valeur";, une copie par langue dans des dossiers comme en.lproj et fr.lproj. NSLocalizedString, String(localized:) et Text lisent sa table, Localizable, sauf si vous en indiquez une autre.

Comment créer un fichier Localizable.strings dans Xcode ?

Choisissez File › New › File from Template, filtrez sur strings, prenez le modèle de fichier de chaînes et nommez-le Localizable. Cliquez ensuite sur Localize dans l’inspecteur de fichier et cochez chaque langue. Pour un nouveau projet, créez plutôt un catalogue de chaînes (Localizable.xcstrings), que Xcode remplit à chaque compilation.

Pourquoi mon Localizable.strings ne fonctionne-t-il pas ?

Si toutes les chaînes d’une langue affichent leur clé, le fichier ne se lit pas : passez plutil -lint et cherchez un point-virgule manquant ou un guillemet non échappé. Sinon, vérifiez que la clé correspond exactement, que le fichier est dans la cible, ainsi que le nom de table, le bundle et toute variable String passée à Text, comme dans la liste ci-dessus.

Localizable.strings est-il obsolète ?

Pas officiellement : il fonctionne toujours, et les catalogues de chaînes deviennent eux-mêmes des fichiers .strings et .stringsdict à la compilation. Mais Apple présente les catalogues comme la méthode recommandée pour localiser les pluriels avec Xcode 15 et ultérieur, et a annoncé à la WWDC23 que le nouveau format remplacera à terme les fichiers strings et stringsdict.

Localizable.strings ou Localizable.xcstrings : lequel choisir ?

Localizable.xcstrings pour tout nouveau travail : un seul fichier pour toutes les langues, pluriels compris, synchronisé avec votre code à chaque compilation. Gardez Localizable.strings seulement tant que votre processus en dépend, puis utilisez Migrate to String Catalog.

Qu’est-ce que le fichier InfoPlist.strings ?

C’est le fichier de chaînes qui traduit les valeurs de Info.plist : le nom de l’app sous l’icône (CFBundleDisplayName) et les demandes d’autorisation (NSCameraUsageDescription et les autres clés NS…UsageDescription). Chaque langue a sa copie dans son dossier .lproj, avec les noms des clés de Info.plist comme clés. Dans un projet à String Catalogs, InfoPlist.xcstrings joue le même rôle. Voir InfoPlist.strings.

De ce guide à votre app publiée

Develak conçoit, développe et publie des apps iOS natives pour des fondateurs et des équipes du monde entier, en français comme en anglais.

  • Icône de l’app Baggd
  • Icône de l’app Corkwell
  • Icône de l’app Cedary
  • Icône de l’app ApexLap
  • Icône de l’app Pillio
  • Icône de l’app SimplyTask
  • Icône de l’app Fosterwell
  • Icône de l’app Contrastly
Les 35 applications
Démarrer un projet