diff --git a/dev/public/js/init.js b/dev/public/js/MARL/init.js
similarity index 78%
rename from dev/public/js/init.js
rename to dev/public/js/MARL/init.js
index 8539d5a..49b9054 100644
--- a/dev/public/js/init.js
+++ b/dev/public/js/MARL/init.js
@@ -23,6 +23,16 @@ document.addEventListener("alpine:init", () => {
   resetStores();
 });
 
+// i18n
+
+let appStrings = {};
+
+for (const lang in appLangs) {
+  const script = document.createElement("script");
+  script.src = `js/i18n/${lang}.js`;
+  document.head.appendChild(script);
+}
+
 document.addEventListener("alpine-i18n:ready", function () {
   AlpineI18n.create("en", appStrings);
   AlpineI18n.fallbackLocale = "en";
diff --git a/dev/public/js/libs.js b/dev/public/js/MARL/libs.js
similarity index 89%
rename from dev/public/js/libs.js
rename to dev/public/js/MARL/libs.js
index b8db65e..4b0e219 100644
--- a/dev/public/js/libs.js
+++ b/dev/public/js/MARL/libs.js
@@ -2,20 +2,20 @@ const isFileProtocol = window.location.protocol === "file:";
 
 const scripts = [
   {
-    src: "js/jszip.min.js",
+    src: "js/libs/jszip.min.js",
     integrity: "sha512-XMVd28F1oH/O71fzwBnV7HucLxVwtxf26XV8P4wPk26EDxuGZ91N8bsOttmnomcCD3CS5ZMRL50H0GgOHvegtg==",
     crossorigin: "anonymous",
     defer: false,
   },
   // Note: Alpine plug-ins must be inserted BEFORE alpinejs
   {
-    src: "js/alpinejs-i18n.min.js",
+    src: "js/libs/alpinejs-i18n.min.js",
     integrity: "sha256-o204NcFyHPFzboSC51fufMqFe2KJdQfSCl8AlvSZO/E=",
     crossorigin: "anonymous",
     defer: true,
   },
   {
-    src: "js/alpinejs.min.js",
+    src: "js/libs/alpinejs.min.js",
     integrity: "sha512-FUaEyIgi9bspXaH6hUadCwBLxKwdH7CW24riiOqA5p8hTNR/RCLv9UpAILKwqs2AN5WtKB52CqbiePBei3qjKg==",
     crossorigin: "anonymous",
     defer: true,
diff --git a/dev/public/js/stores.js b/dev/public/js/MARL/stores.js
similarity index 100%
rename from dev/public/js/stores.js
rename to dev/public/js/MARL/stores.js
diff --git a/dev/public/js/utils.js b/dev/public/js/MARL/utils.js
similarity index 100%
rename from dev/public/js/utils.js
rename to dev/public/js/MARL/utils.js
diff --git a/dev/public/js/i18n/_langs.js b/dev/public/js/i18n/_langs.js
new file mode 100644
index 0000000..7f67997
--- /dev/null
+++ b/dev/public/js/i18n/_langs.js
@@ -0,0 +1,4 @@
+const appLangs = {
+  en: "English",
+  fr: "Français",
+};
diff --git a/dev/public/js/i18n/en.js b/dev/public/js/i18n/en.js
new file mode 100644
index 0000000..cc70f80
--- /dev/null
+++ b/dev/public/js/i18n/en.js
@@ -0,0 +1,150 @@
+appStrings["en"] = {
+  welcome: {
+    title: "Welcome to {appName}",
+    p1: `MARL allows you to explore the content of your Mastodon archive file in a
+      user-friendly interface. Everything takes place in the browser: your archive stays
+      strictly on your computer; none of its data is sent to any server.`,
+    p2: `You can request your Mastodon archive by logging into your account on the web,
+      then visiting "Preferences > Import and export > Request your archive".<br />
+      <strong>Please note:</strong> only ZIP files are supported (not GZ).`,
+    p3: `<strong>Start by opening your archive file with MARL.</strong><br />
+      You can drag and drop it anywhere on this page, or
+      {labelStart}click here to select it{labelEnd}.`,
+  },
+  misc: {
+    loading: "Loading",
+    closePanelBtn: "Close panel",
+  },
+  menu: {
+    profile: "Profile",
+    filters: "Filters",
+    filtersActive: "some filters are active",
+    tags: "Tags",
+    tools: "Tools",
+  },
+  lightbox: {
+    next: "Next image",
+    prev: "Previous image",
+    close: "Close image",
+  },
+  actor: {
+    accountInfo: "Account info",
+    accounts: "Accounts",
+    noAvatarImage: "No avatar image",
+    noHeaderImage: "No header image",
+    headerImage: "Header",
+    memberSince: "Member since",
+    countPosts: "posts",
+    countInArchive: "in archive",
+    countDiffWhy: "Why are those two numbers different?",
+    countDiffExplanation: `Posts that are not directly hosted on your instance are kept
+      in a cache by your instance for a given time, after what they are deleted from that
+      cache. Posts that are not in your instance cache any more are not included in your
+      archive. This affects boosts, likes, and bookmarks.`,
+    rawData: "Raw data {fileName}",
+    likes: "Favorites",
+    likesEmpty: "no favorites",
+    bookmarks: "Bookmarks",
+    bookmarksEmpty: "no bookmarks",
+  },
+  filters: {
+    panelTitle: "Filter posts",
+    panelNotice: `The list of posts will be automatically updated based on the active
+      filters below.`,
+    fullText: "Full text",
+    hashtagText: "Hashtags",
+    mentionText: "Mentions",
+    externalLink: "External links",
+    summary: "Summary (CW)",
+    isEdited: "Has been edited",
+    isDuplicate: "Non-exact duplicates",
+
+    mustContain: "Must contain",
+    hasHashtags: "Hashtag(s)",
+    hasMentions: "Mention(s)",
+    hasExternalLink: "External link(s)",
+    hasSummary: "Summary (CW)",
+
+    type: "Type",
+    typeOriginal: "Original posts (incl. replies)",
+    typeBoost: "Boosts",
+    noStartingAt: 'Does not start with "@"',
+    isSensitive: "Marked as sensitive",
+
+    mustHaveAttachement: "Must have attachment",
+    attachmentAny: "Any type",
+    attachmentImage: "Image(s)",
+    attachmentVideo: "Video(s)",
+    attachmentSound: "Sound(s)",
+    attachmentNoAltText: "Without alt text",
+    attachmentWithAltText: "With alt text",
+
+    visibility: "Visibility",
+    visibilityPublic: "Public",
+    visibilityUnlisted: "Unlisted",
+    visibilityFollowers: "Followers only",
+    visibilityMentioned: "Mentioned people only",
+
+    language: "Language",
+    author: "Author",
+
+    resetFilters: "Reset filters",
+  },
+  header: {
+    countLabel: "posts",
+    oldestFirst: "oldest first",
+    latestFirst: "latest first",
+    reverse: "Reverse",
+    loadNewFile: "Load new file",
+  },
+  paging: {
+    first: "First",
+    prev: "Prev",
+    next: "Next",
+    last: "Last",
+    pagingOptions: "Paging options",
+    page: "Page",
+    postsPerPage: "posts per page",
+    reverseOrder: "Reverse order",
+  },
+  posts: {
+    panelTitle: "Posts",
+    noResults: "No results for the specified filters",
+    noPostsError: "No posts found in archive",
+  },
+  post: {
+    by: "by",
+    lastUpdated: "Last updated",
+    linkToPost: "link",
+    attachmentNoAlt: "No description provided",
+    attachmentInArchive: "In archive:",
+    people: "People",
+    hashtags: "Hashtags",
+    extLinks: "External links",
+    rawData: "Raw data",
+  },
+  tags: {
+    panelTitle: "Tags",
+    hashtags: "Hashtags",
+    mentions: "Mentions",
+    boosts: "Boosted users",
+    hashtagsFilter: "Filter hashtags",
+    mentionsFilter: "Filter mentions",
+    boostsFilter: "Filter boosted users",
+  },
+  tools: {
+    panelTitle: "Tools",
+    appSettings: "App settings",
+    selectLanguage: "Select language",
+    useDarkTheme: "Use dark theme",
+    useLightTheme: "Use light theme",
+    loadedFiles: "Loaded files",
+    addAnother: "Add another archive",
+    addAnotherTip:
+      "Tip: You can open multiple archives at once.<br>You can also drag and drop your archive files anywhere on this window.",
+    startOver: "Start over",
+    startOverConfirm: "Discard current data and load a new archive file?",
+    appLog: "App log",
+    projectPage: `Project page (github)`,
+  },
+};
diff --git a/dev/public/js/i18n/fr.js b/dev/public/js/i18n/fr.js
new file mode 100644
index 0000000..70b6eba
--- /dev/null
+++ b/dev/public/js/i18n/fr.js
@@ -0,0 +1,150 @@
+appStrings["fr"] = {
+  welcome: {
+    title: "Bienvenue dans {appName}",
+    p1: `MARL vous permet d'explorer le contenu de votre archive Mastodon dans une
+        interface simple d'utilisation. Tout se passe dans votre navigateur : votre archive
+        reste sur votre appareil; aucune donnée n'est envoyée à aucun serveur.`,
+    p2: `Vous pouvez demander votre archive Mastodon en vous identifiant avec votre compte
+        sur le web, puis en visitant "Préférences >Import et export >Demandez vos archives".<br />
+        <strong>Important :</strong> seuls les fichiers ZIP sont acceptés (pas les fichiers GZ).`,
+    p3: `<strong>Commencez par ouvrir votre archive avec MARL.</strong><br />
+        Vous pouvez la glisser-déposer n'importe où sur cette page, ou
+        {labelStart}cliquer ici pour la sélectionner{labelEnd}.`,
+  },
+  misc: {
+    loading: "Chargement",
+    closePanelBtn: "Fermer le panneau",
+  },
+  menu: {
+    profile: "Profil",
+    filters: "Filtres",
+    filtersActive: "certains filtres sont actifs",
+    tags: "Tags",
+    tools: "Outils",
+  },
+  lightbox: {
+    next: "Image suivante",
+    prev: "Image précédente",
+    close: "Fermer l'image",
+  },
+  actor: {
+    accountInfo: "Infos du compte",
+    accounts: "Comptes",
+    noAvatarImage: "Pas d'avatar",
+    noHeaderImage: "pas d'image d'en-tête",
+    headerImage: "En-tête",
+    memberSince: "Membre depuis",
+    countPosts: "posts",
+    countInArchive: "dans l'archive",
+    countDiffWhy: "Pourquoi ces deux nombres sont-ils différents ?",
+    countDiffExplanation: `Les posts qui ne sont pas hébergés directement sur votre instance
+        sont gardés en cache par celle-ci pour une durée limitée, après quoi ils sont supprimés
+        de ce cache. Les posts qui ne sont plus présents dans le cache de votre instance ne sont
+        pas inclus dans votre archive. Cela concerne les partages, les favoris et les marque-pages.`,
+    rawData: "Données brutes {fileName}",
+    likes: "Favoris",
+    likesEmpty: "aucun favori",
+    bookmarks: "Marque-pages",
+    bookmarksEmpty: "aucun marque-page",
+  },
+  filters: {
+    panelTitle: "Filtrer les posts",
+    panelNotice: `La liste des posts sera automatiquement mise à jour en fonction des filtres
+        activés ci-dessous.`,
+    fullText: "Partout",
+    hashtagText: "Hashtags",
+    mentionText: "Mentions",
+    externalLink: "Liens externes",
+    summary: "Avertissement de contenu",
+    isEdited: "A été modifié",
+    isDuplicate: "Doublons imparfaits",
+
+    mustContain: "Doit contenir",
+    hasHashtags: "Hashtag(s)",
+    hasMentions: "Mention(s)",
+    hasExternalLink: "Lien(s) externe(s)",
+    hasSummary: "Avertissement de contenu",
+
+    type: "Type",
+    typeOriginal: "Posts originaux (y.c. réponses)",
+    typeBoost: "Partages",
+    noStartingAt: 'Ne commence pas par "@"',
+    isSensitive: "Marqué comme sensible",
+
+    mustHaveAttachement: "Doit avoir un fichier joint",
+    attachmentAny: "N'importe quel type",
+    attachmentImage: "Image(s)",
+    attachmentVideo: "Vidéo(s)",
+    attachmentSound: "Son(s)",
+    attachmentNoAltText: "Sans description alternative",
+    attachmentWithAltText: "Avec description alternative",
+
+    visibility: "Confidentialité",
+    visibilityPublic: "Public",
+    visibilityUnlisted: "Public discret",
+    visibilityFollowers: "Abonnés",
+    visibilityMentioned: "Personnes spécifiques",
+
+    language: "Langue",
+    author: "Auteur",
+
+    resetFilters: "Réinitialiser les filtres",
+  },
+  header: {
+    countLabel: "posts",
+    oldestFirst: "les plus anciens d'abord",
+    latestFirst: "les plus récents d'abord",
+    reverse: "Inverser",
+    loadNewFile: "Charger un nouveau fichier",
+  },
+  paging: {
+    first: "Première",
+    prev: "Précédente",
+    next: "Suivante",
+    last: "Dernière",
+    pagingOptions: "Options de pagination",
+    page: "Page",
+    postsPerPage: "posts par page",
+    reverseOrder: "Inverser l'ordre",
+  },
+  posts: {
+    panelTitle: "Posts",
+    noResults: "Pas de résultats pour les filtres spécifiés",
+    noPostsError: "Aucun post trouvé dans l'archive",
+  },
+  post: {
+    by: "par",
+    lastUpdated: "Dernière modification",
+    linkToPost: "lien",
+    attachmentNoAlt: "Aucune description fournie",
+    attachmentInArchive: "Dans l'archive :",
+    people: "Personnes",
+    hashtags: "Hashtags",
+    extLinks: "Liens externes",
+    rawData: "Données brutes",
+  },
+  tags: {
+    panelTitle: "Tags",
+    hashtags: "Hashtags",
+    mentions: "Mentions",
+    boosts: "Utilisateurs partagés",
+    hashtagsFilter: "Filtrer les hashtags",
+    mentionsFilter: "Filtrer les mentions",
+    boostsFilter: "Filter utilisateurs partagés",
+  },
+  tools: {
+    panelTitle: "Outils",
+    appSettings: "Réglages de l'app",
+    selectLanguage: "Choisir la langue",
+    useDarkTheme: "Utiliser le thème sombre",
+    useLightTheme: "Utiliser le thème clair",
+    loadedFiles: "Fichiers chargés",
+    addAnother: "Ajouter une autre archive",
+    addAnotherTip:
+      "Astuce: Vous pouvez ouvrir plusieurs archives en même temps.<br>Vous pouvez aussi glisser-déposer vos fichiers d'archive n'importe où dans cette fenêtre.",
+    startOver: "Recommencer",
+    startOverConfirm: "Repartir de zéro et charger un nouveau fichier ?",
+    appLog: "Journal",
+    projectPage: `Page du project (github)`,
+  },
+};
diff --git a/dev/public/js/alpinejs-i18n.min.js b/dev/public/js/libs/alpinejs-i18n.min.js
similarity index 100%
rename from dev/public/js/alpinejs-i18n.min.js
rename to dev/public/js/libs/alpinejs-i18n.min.js
diff --git a/dev/public/js/alpinejs.min.js b/dev/public/js/libs/alpinejs.min.js
similarity index 100%
rename from dev/public/js/alpinejs.min.js
rename to dev/public/js/libs/alpinejs.min.js
diff --git a/dev/public/js/jszip.min.js b/dev/public/js/libs/jszip.min.js
similarity index 100%
rename from dev/public/js/jszip.min.js
rename to dev/public/js/libs/jszip.min.js
diff --git a/dev/public/js/strings.js b/dev/public/js/strings.js
deleted file mode 100644
index 1a31ea5..0000000
--- a/dev/public/js/strings.js
+++ /dev/null
@@ -1,308 +0,0 @@
-const appLangs = {
-  en: "English",
-  fr: "Français",
-};
-
-const appStrings = {
-  en: {
-    welcome: {
-      title: "Welcome to {appName}",
-      p1: `MARL allows you to explore the content of your Mastodon archive file in a
-        user-friendly interface. Everything takes place in the browser: your archive stays
-        strictly on your computer; none of its data is sent to any server.`,
-      p2: `You can request your Mastodon archive by logging into your account on the web,
-        then visiting "Preferences > Import and export > Request your archive".<br />
-        <strong>Please note:</strong> only ZIP files are supported (not GZ).`,
-      p3: `<strong>Start by opening your archive file with MARL.</strong><br />
-        You can drag and drop it anywhere on this page, or
-        {labelStart}click here to select it{labelEnd}.`,
-    },
-    misc: {
-      loading: "Loading",
-      closePanelBtn: "Close panel",
-    },
-    menu: {
-      profile: "Profile",
-      filters: "Filters",
-      filtersActive: "some filters are active",
-      tags: "Tags",
-      tools: "Tools",
-    },
-    lightbox: {
-      next: "Next image",
-      prev: "Previous image",
-      close: "Close image",
-    },
-    actor: {
-      accountInfo: "Account info",
-      accounts: "Accounts",
-      noAvatarImage: "No avatar image",
-      noHeaderImage: "No header image",
-      headerImage: "Header",
-      memberSince: "Member since",
-      countPosts: "posts",
-      countInArchive: "in archive",
-      countDiffWhy: "Why are those two numbers different?",
-      countDiffExplanation: `Posts that are not directly hosted on your instance are kept
-        in a cache by your instance for a given time, after what they are deleted from that
-        cache. Posts that are not in your instance cache any more are not included in your
-        archive. This affects boosts, likes, and bookmarks.`,
-      rawData: "Raw data {fileName}",
-      likes: "Favorites",
-      likesEmpty: "no favorites",
-      bookmarks: "Bookmarks",
-      bookmarksEmpty: "no bookmarks",
-    },
-    filters: {
-      panelTitle: "Filter posts",
-      panelNotice: `The list of posts will be automatically updated based on the active
-        filters below.`,
-      fullText: "Full text",
-      hashtagText: "Hashtags",
-      mentionText: "Mentions",
-      externalLink: "External links",
-      summary: "Summary (CW)",
-      isEdited: "Has been edited",
-      isDuplicate: "Non-exact duplicates",
-
-      mustContain: "Must contain",
-      hasHashtags: "Hashtag(s)",
-      hasMentions: "Mention(s)",
-      hasExternalLink: "External link(s)",
-      hasSummary: "Summary (CW)",
-
-      type: "Type",
-      typeOriginal: "Original posts (incl. replies)",
-      typeBoost: "Boosts",
-      noStartingAt: 'Does not start with "@"',
-      isSensitive: "Marked as sensitive",
-
-      mustHaveAttachement: "Must have attachment",
-      attachmentAny: "Any type",
-      attachmentImage: "Image(s)",
-      attachmentVideo: "Video(s)",
-      attachmentSound: "Sound(s)",
-      attachmentNoAltText: "Without alt text",
-      attachmentWithAltText: "With alt text",
-
-      visibility: "Visibility",
-      visibilityPublic: "Public",
-      visibilityUnlisted: "Unlisted",
-      visibilityFollowers: "Followers only",
-      visibilityMentioned: "Mentioned people only",
-
-      language: "Language",
-      author: "Author",
-
-      resetFilters: "Reset filters",
-    },
-    header: {
-      countLabel: "posts",
-      oldestFirst: "oldest first",
-      latestFirst: "latest first",
-      reverse: "Reverse",
-      loadNewFile: "Load new file",
-    },
-    paging: {
-      first: "First",
-      prev: "Prev",
-      next: "Next",
-      last: "Last",
-      pagingOptions: "Paging options",
-      page: "Page",
-      postsPerPage: "posts per page",
-      reverseOrder: "Reverse order",
-    },
-    posts: {
-      panelTitle: "Posts",
-      noResults: "No results for the specified filters",
-      noPostsError: "No posts found in archive",
-    },
-    post: {
-      by: "by",
-      lastUpdated: "Last updated",
-      linkToPost: "link",
-      attachmentNoAlt: "No description provided",
-      attachmentInArchive: "In archive:",
-      people: "People",
-      hashtags: "Hashtags",
-      extLinks: "External links",
-      rawData: "Raw data",
-    },
-    tags: {
-      panelTitle: "Tags",
-      hashtags: "Hashtags",
-      mentions: "Mentions",
-      boosts: "Boosted users",
-      hashtagsFilter: "Filter hashtags",
-      mentionsFilter: "Filter mentions",
-      boostsFilter: "Filter boosted users",
-    },
-    tools: {
-      panelTitle: "Tools",
-      appSettings: "App settings",
-      selectLanguage: "Select language",
-      useDarkTheme: "Use dark theme",
-      useLightTheme: "Use light theme",
-      loadedFiles: "Loaded files",
-      addAnother: "Add another archive",
-      addAnotherTip:
-        "Tip: You can open multiple archives at once.<br>You can also drag and drop your archive files anywhere on this window.",
-      startOver: "Start over",
-      startOverConfirm: "Discard current data and load a new archive file?",
-      appLog: "App log",
-      projectPage: `Project page (github)`,
-    },
-  },
-
-  fr: {
-    welcome: {
-      title: "Bienvenue dans {appName}",
-      p1: `MARL vous permet d'explorer le contenu de votre archive Mastodon dans une
-        interface simple d'utilisation. Tout se passe dans votre navigateur : votre archive
-        reste sur votre appareil; aucune donnée n'est envoyée à aucun serveur.`,
-      p2: `Vous pouvez demander votre archive Mastodon en vous identifiant avec votre compte
-        sur le web, puis en visitant "Préférences >Import et export >Demandez vos archives".<br />
-        <strong>Important :</strong> seuls les fichiers ZIP sont acceptés (pas les fichiers GZ).`,
-      p3: `<strong>Commencez par ouvrir votre archive avec MARL.</strong><br />
-        Vous pouvez la glisser-déposer n'importe où sur cette page, ou
-        {labelStart}cliquer ici pour la sélectionner{labelEnd}.`,
-    },
-    misc: {
-      loading: "Chargement",
-      closePanelBtn: "Fermer le panneau",
-    },
-    menu: {
-      profile: "Profil",
-      filters: "Filtres",
-      filtersActive: "certains filtres sont actifs",
-      tags: "Tags",
-      tools: "Outils",
-    },
-    lightbox: {
-      next: "Image suivante",
-      prev: "Image précédente",
-      close: "Fermer l'image",
-    },
-    actor: {
-      accountInfo: "Infos du compte",
-      accounts: "Comptes",
-      noAvatarImage: "Pas d'avatar",
-      noHeaderImage: "pas d'image d'en-tête",
-      headerImage: "En-tête",
-      memberSince: "Membre depuis",
-      countPosts: "posts",
-      countInArchive: "dans l'archive",
-      countDiffWhy: "Pourquoi ces deux nombres sont-ils différents ?",
-      countDiffExplanation: `Les posts qui ne sont pas hébergés directement sur votre instance
-        sont gardés en cache par celle-ci pour une durée limitée, après quoi ils sont supprimés
-        de ce cache. Les posts qui ne sont plus présents dans le cache de votre instance ne sont
-        pas inclus dans votre archive. Cela concerne les partages, les favoris et les marque-pages.`,
-      rawData: "Données brutes {fileName}",
-      likes: "Favoris",
-      likesEmpty: "aucun favori",
-      bookmarks: "Marque-pages",
-      bookmarksEmpty: "aucun marque-page",
-    },
-    filters: {
-      panelTitle: "Filtrer les posts",
-      panelNotice: `La liste des posts sera automatiquement mise à jour en fonction des filtres
-        activés ci-dessous.`,
-      fullText: "Partout",
-      hashtagText: "Hashtags",
-      mentionText: "Mentions",
-      externalLink: "Liens externes",
-      summary: "Avertissement de contenu",
-      isEdited: "A été modifié",
-      isDuplicate: "Doublons imparfaits",
-
-      mustContain: "Doit contenir",
-      hasHashtags: "Hashtag(s)",
-      hasMentions: "Mention(s)",
-      hasExternalLink: "Lien(s) externe(s)",
-      hasSummary: "Avertissement de contenu",
-
-      type: "Type",
-      typeOriginal: "Posts originaux (y.c. réponses)",
-      typeBoost: "Partages",
-      noStartingAt: 'Ne commence pas par "@"',
-      isSensitive: "Marqué comme sensible",
-
-      mustHaveAttachement: "Doit avoir un fichier joint",
-      attachmentAny: "N'importe quel type",
-      attachmentImage: "Image(s)",
-      attachmentVideo: "Vidéo(s)",
-      attachmentSound: "Son(s)",
-      attachmentNoAltText: "Sans description alternative",
-      attachmentWithAltText: "Avec description alternative",
-
-      visibility: "Confidentialité",
-      visibilityPublic: "Public",
-      visibilityUnlisted: "Public discret",
-      visibilityFollowers: "Abonnés",
-      visibilityMentioned: "Personnes spécifiques",
-
-      language: "Langue",
-      author: "Auteur",
-
-      resetFilters: "Réinitialiser les filtres",
-    },
-    header: {
-      countLabel: "posts",
-      oldestFirst: "les plus anciens d'abord",
-      latestFirst: "les plus récents d'abord",
-      reverse: "Inverser",
-      loadNewFile: "Charger un nouveau fichier",
-    },
-    paging: {
-      first: "Première",
-      prev: "Précédente",
-      next: "Suivante",
-      last: "Dernière",
-      pagingOptions: "Options de pagination",
-      page: "Page",
-      postsPerPage: "posts par page",
-      reverseOrder: "Inverser l'ordre",
-    },
-    posts: {
-      panelTitle: "Posts",
-      noResults: "Pas de résultats pour les filtres spécifiés",
-      noPostsError: "Aucun post trouvé dans l'archive",
-    },
-    post: {
-      by: "par",
-      lastUpdated: "Dernière modification",
-      linkToPost: "lien",
-      attachmentNoAlt: "Aucune description fournie",
-      attachmentInArchive: "Dans l'archive :",
-      people: "Personnes",
-      hashtags: "Hashtags",
-      extLinks: "Liens externes",
-      rawData: "Données brutes",
-    },
-    tags: {
-      panelTitle: "Tags",
-      hashtags: "Hashtags",
-      mentions: "Mentions",
-      boosts: "Utilisateurs partagés",
-      hashtagsFilter: "Filtrer les hashtags",
-      mentionsFilter: "Filtrer les mentions",
-      boostsFilter: "Filter utilisateurs partagés",
-    },
-    tools: {
-      panelTitle: "Outils",
-      appSettings: "Réglages de l'app",
-      selectLanguage: "Choisir la langue",
-      useDarkTheme: "Utiliser le thème sombre",
-      useLightTheme: "Utiliser le thème clair",
-      loadedFiles: "Fichiers chargés",
-      addAnother: "Ajouter une autre archive",
-      addAnotherTip:
-        "Astuce: Vous pouvez ouvrir plusieurs archives en même temps.<br>Vous pouvez aussi glisser-déposer vos fichiers d'archive n'importe où dans cette fenêtre.",
-      startOver: "Recommencer",
-      startOverConfirm: "Repartir de zéro et charger un nouveau fichier ?",
-      appLog: "Journal",
-      projectPage: `Page du project (github)`,
-    },
-  },
-};
diff --git a/dev/src/pages/index.astro b/dev/src/pages/index.astro
index dd1c643..be471b9 100644
--- a/dev/src/pages/index.astro
+++ b/dev/src/pages/index.astro
@@ -1,5 +1,6 @@
 ---
 import '../css/main.scss';
+
 import App from '../components/App.astro';
 import SvgSprites from '../components/SvgSprites.astro';
 ---
@@ -21,10 +22,10 @@ import SvgSprites from '../components/SvgSprites.astro';
 		<App />
 		<SvgSprites />
 
-    <script src="/js/strings.js" is:inline></script>
-    <script src="/js/stores.js" is:inline></script>
-    <script src="/js/utils.js" is:inline></script>
-    <script src="/js/libs.js" is:inline></script>
-    <script src="/js/init.js" is:inline></script>
+    <script src="/js/i18n/_langs.js" is:inline></script>
+    <script src="/js/MARL/stores.js" is:inline></script>
+    <script src="/js/MARL/utils.js" is:inline></script>
+    <script src="/js/MARL/libs.js" is:inline></script>
+    <script src="/js/MARL/init.js" is:inline></script>
 	</body>
 </html>