diff --git a/bin/generate_l10n.php b/bin/generate_l10n.php
new file mode 100644
index 0000000..0ab6418
--- /dev/null
+++ b/bin/generate_l10n.php
@@ -0,0 +1,31 @@
+=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
+EOF;
+}
+
+function generateJsonContent($translations) {
+ $datas = [
+ 'translations' => $translations,
+ 'pluralForm' => 'nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;',
+ ];
+
+ return json_encode(
+ $datas,
+ JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
+ );
+}
+
+chdir(__DIR__.'/../');
+
+foreach (glob('src/l10n/fixtures/*.yaml') as $file) {
+ $lang = str_replace('.yaml', '', basename($file));
+ $translations = yaml_parse(file_get_contents($file));
+
+ file_put_contents('l10n/'.$lang.'.js', generateJsContent($translations));
+ file_put_contents('l10n/'.$lang.'.json', generateJsonContent($translations));
+}
diff --git a/src/l10n/fixtures/fr.yaml b/src/l10n/fixtures/fr.yaml
new file mode 100644
index 0000000..f578a7e
--- /dev/null
+++ b/src/l10n/fixtures/fr.yaml
@@ -0,0 +1,47 @@
+"Side menu": "Menu latéral"
+"No": "Non"
+"Yes": "Oui"
+"Menu": "Menu"
+'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.': 'Utiliser le raccourcis clavier Ctrl+o pour ouvrir et fermer le menu latéral. Utiliser tab pour naviguer.'
+"Top menu": "Menu supérieur"
+"Apps that not must be moved in the side menu": "Les applications qui ne doivent pas être affichées dans le menu latéral"
+"If there is no selection then the global configuration is applied.": "Si il n'y a aucune sélection alors la configuration globale sera appliquée"
+"Experimental": "Expérimental"
+"Save": "Sauvegarder"
+"You like this app and you want to support me?": "Vous aimer cette application et vous souhaitez m'aider ?"
+"Buy me a coffe ☕": "Offrez moi un café ☕"
+"Hidden": "Caché"
+"Small": "Petit"
+"Normal": "Normal"
+"Big": "Gros"
+"Colors": "Couleurs"
+"Background color": "Couleur de fond"
+"Background color of current app": "Couleur de fond de l'application en cours"
+"Text color": "Couleur du texte"
+"Loader": "Indicateur de chargement"
+"Icon": "Icône"
+"Same color": "Même couleur"
+"Opposite color": "Couleur opposée"
+"Transparent": "Transparent"
+"Opaque": "Opaque"
+"Opener": "Bouton d'ouverture"
+"Default": "Par défaut"
+"Default (dark)": "Par défaut (sombre)"
+"Hamburger": "Hamburger"
+"Hamburger (dark)": "Hamburger (sombre)"
+"Hamburger 2": "Hamburger 2"
+"Hamburger 2 (dark)": "Hamburger 2 (sombre)"
+"Before the logo": "Avant le logo"
+"After the logo": "Après le logo"
+"Position": "Position"
+"Show only the opener (hidden logo)": "Afficher uniquement le bouton d'ouverture (masquer le logo)"
+"Do not display the side menu and the opener if there is no application (eg: public pages).": "Ne pas afficher le menu latéral et le bouton d'ouverture s'il n'y a aucune application (exemple : page publiques)."
+"Panel": "Panneau"
+"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Ouvrir le menu au passage de la souris (automatiquement désactivé sur les écrans tactiles)"
+"Display the big menu": "Afficher le menu large"
+"The big menu is not compatible with AppOrder.": "Le menu large n'est pas compatible avec l'application AppOrder"
+"Display the logo": "Afficher le logo"
+"This feature is not compatible with the big menu
display.": "Cette fonctionnalité n'est pas compatible avec l'affichage du menu large."
+"Icons and texts": "Icônes et textes"
+"Loader enabled": "Activation de l'indicateur de chargement"
+"Tips": "Astuces"