diff --git a/app/Language/de/Home.php b/app/Language/de/Home.php
index 26800742fcf2fa53ce0b6fbc92442df2f0c2d61e..a05205c543fe583e278e7393119c00c48671d623 100644
--- a/app/Language/de/Home.php
+++ b/app/Language/de/Home.php
@@ -16,5 +16,5 @@ return [
         'created_desc' => 'Neueste zuerst',
         'created_asc' => 'Älteste zuerst',
     ],
-    'no_podcast' => 'Keinen Podcast gefunden',
+    'no_podcast' => 'Keine Podcasts gefunden',
 ];
diff --git a/docs/src/ca/index.md b/docs/src/ca/index.md
index 12326ac99d34f1570861530608e6d1f3219d01fa..12e17c193a8389a2213c4c56df3ed9917b86051b 100644
--- a/docs/src/ca/index.md
+++ b/docs/src/ca/index.md
@@ -134,8 +134,8 @@ There are many solutions for you to host your podcasts, some of which are really
 great and [a lot of them](https://podcastindex.org/apps) are jumping into the
 Podcasting 2.0 wagon just like Castopod!
 
-Cadascuna d'aquestes solucions difereix entre si, podeu comparar-les amb la
-[llista de funcions](#característiques).
+Each of these solutions differ from one another, you may compare with the
+[list of features](#features).
 
 That being said, there are two main differences with other podcasting solutions:
 
@@ -161,9 +161,9 @@ so that you can understand what actions will and will not be tolerated.
 
 ### Guia de col·laboració
 
-Llegiu la nostra [guia de col·laboració](../contributing/guidelines.md) per
-conèixer el nostre procés de desenvolupament, com proposar correccions d'errors
-i millores, i com construir i prova els teus canvis a Castopod.
+Read our [contributing guide](./contributing/guidelines.md) to learn about our
+development process, how to propose bugfixes and improvements, and how to build
+and test your changes to Castopod.
 
 ## Col·laboradors ✨
 
diff --git a/docs/src/es/getting-started/update.md b/docs/src/es/getting-started/update.md
index 78d6c13ddcfce3853e92c6e6735bfd431e8f49d7..d69fd09b3ddcbd41b0cf6252feef732a7185e5d1 100644
--- a/docs/src/es/getting-started/update.md
+++ b/docs/src/es/getting-started/update.md
@@ -62,7 +62,8 @@ la página de
 [lanzamientos](https://code.castopod.org/adaures/castopod/-/releases)).
 
 - cf.
-  [No he actualizado mi instancia en mucho tiempo… ¿Qué debo hacer?](#no-he-actualizado-mi-instancia-en-mucho-tiempo-qué-debo-hacer)
+
+No he actualizado mi instancia en mucho tiempo… ¿Qué debo hacer?</li> </ul>
 
 :::
 
diff --git a/docs/src/fr/getting-started/update.md b/docs/src/fr/getting-started/update.md
index ef4f2fdb141d2dd009aa425264c583e6662f7e4d..e7bc8e871805a055b9b2199a18bdbca7ffa64d5f 100644
--- a/docs/src/fr/getting-started/update.md
+++ b/docs/src/fr/getting-started/update.md
@@ -61,8 +61,8 @@ Les versions peuvent être accompagnées d'instructions de mise à jour
 supplémentaires (cf. la
 [page des notes de versions](https://code.castopod.org/adaures/castopod/-/releases)).
 
-- cf.
-  [Je n'ai pas mis à jour mon instance depuis longtemps… Que devrais-je faire ?](#je-nai-pas-mis-à-jour-mon-instance-depuis-longtemps-que-devrais-je-faire)
+- Je n'ai pas mis à jour mon instance depuis longtemps… Que devrais-je faire
+  ?</a>
 
 :::
 
diff --git a/docs/src/fr2/getting-started/security.md b/docs/src/fr2/getting-started/security.md
new file mode 100644
index 0000000000000000000000000000000000000000..e205698df8a8029f080840922a212f01da1baa7e
--- /dev/null
+++ b/docs/src/fr2/getting-started/security.md
@@ -0,0 +1,26 @@
+---
+title: Security
+---
+
+# Security concerns
+
+Castopod is built on top of [CodeIgniter4](https://codeigniter.com/), a PHP
+framework that encourages
+[good security practices](https://codeigniter.com/user_guide/concepts/security.html).
+
+To maximize your instance's safety and prevent any malicious attack, we
+recommend you update all your Castopod files permissions after installation or
+updates (to avoid any prior permission error):
+
+- `writable/` folder must be **readable** and **writable**.
+- `public/media/` folder must be **readable** and **writable**.
+- any other file must be set to **readonly**.
+
+For instance, if you are using Apache or NGINX with Ubuntu you may do the
+following:
+
+```bash
+sudo chown -R root:root /path/to/castopod
+sudo chown -R www-data:www-data /path/to/castopod/writable
+sudo chown -R www-data:www-data /path/to/castopod/public/media
+```
diff --git a/docs/src/fr2/getting-started/update.md b/docs/src/fr2/getting-started/update.md
new file mode 100644
index 0000000000000000000000000000000000000000..98e019fbc7a9adefc88b183b9f166599709297e2
--- /dev/null
+++ b/docs/src/fr2/getting-started/update.md
@@ -0,0 +1,109 @@
+---
+title: Update
+sidebarDepth: 3
+---
+
+# How to update Castopod?
+
+After installing Castopod, you may want to update your instance to the latest
+version in order to enjoy the latest features ✨, bug fixes 🐛 and performance
+improvements âš¡.
+
+## Update instructions
+
+0. ⚠️ Before any update, we highly recommend you backup your Castopod files and
+   database.
+
+   - cf.
+     [Should I make a backup before updating?](#should-i-make-a-backup-before-updating)
+
+1. Go to the
+   [releases page](https://code.castopod.org/adaures/castopod/-/releases) and
+   see if your instance is up to date with the latest Castopod version
+
+   - cf.
+     [Where can I find my Castopod version?](#where-can-i-find-my-castopod-version)
+
+2. Download the latest release package named `Castopod Package`, you may choose
+   between the `zip` or `tar.gz` archives
+
+   - ⚠️ Make sure you download the Castopod Package and **NOT** the Source Code
+   - Note that you can also download the latest package from
+     [castopod.org](https://castopod.org/)
+
+3. On your server:
+
+   - Remove all files except `.env` and `public/media`
+   - Copy the new files from the downloaded package into your server
+
+     ::: info Note
+
+     You may need to reset files permissions as during the install process.
+     Check [Security Concerns](./security.md).
+
+     :::
+
+4. Update your database schema from your `Castopod Admin` > `About` page or by
+   running:
+
+   ```bash
+   php spark castopod:database-update
+   ```
+
+5. Clear your cache from your `Castopod Admin` > `Settings` > `general` >
+   `Housekeeping`
+6. ✨ Enjoy your fresh instance, you're all done!
+
+::: info Note
+
+Releases may come with additional update instructions (see
+[releases page](https://code.castopod.org/adaures/castopod/-/releases)).
+
+- cf.
+  [I haven't updated my instance in a long time… What should I do?](#i-havent-updated-my-instance-in-a-long-time-what-should-i-do)
+
+:::
+
+## Fully Automated updates
+
+> Coming soon... 👀
+
+## Frequently asked questions (FAQ)
+
+### Where can I find my Castopod version?
+
+Go to your Castopod admin panel, the version is displayed on the bottom left
+corner.
+
+Alternatively, you can find the version in the `app > Config > Constants.php`
+file.
+
+### I haven't updated my instance in a long time… What should I do?
+
+No problem! Just get the latest release as described above. Only, when going
+through the release instructions (4), perform them sequentially, from the oldest
+to the newest.
+
+> You may want to backup your instance depending on how long you haven't updated
+> Castopod.
+
+For example, if you're on `v1.0.0-alpha.42` and would like to upgrade to
+`v1.0.0-beta.1`:
+
+0. (highly recommended) Make a backup of your files and database.
+
+1. Download the latest release, overwrite your files whilst keeping `.env` and
+   `public/media`.
+
+2. Go through each release update instructions sequentially (from oldest to
+   newest) starting with `v1.0.0-alpha.43`, `v1.0.0-alpha.44`,
+   `v1.0.0-alpha.45`, …, `v1.0.0-beta.1`.
+
+3. ✨ Enjoy your fresh instance, you're all done!
+
+### Should I make a backup before updating?
+
+We advise you do, so you don't lose everything if anything goes wrong!
+
+More generally, we advise you make regular backups of your Castopod files and
+database to prevent you from losing it all…
diff --git a/docs/src/fr_CA/index.md b/docs/src/fr_CA/index.md
index e17afd7360bca5d5569e618a0a3c89fb6689e13a..08b037f5f9151efee4a8776ddda5aa760517206f 100644
--- a/docs/src/fr_CA/index.md
+++ b/docs/src/fr_CA/index.md
@@ -159,7 +159,7 @@ so that you can understand what actions will and will not be&nbsp;tolerated.
 
 ### Contributing guide
 
-Read our [contributing guide](../contributing/guidelines.md) to learn about our
+Read our [contributing guide](./contributing/guidelines.md) to learn about our
 development process, how to propose bugfixes and improvements, and how to build
 and test your changes to Castopod.
 
diff --git a/docs/src/gd/index.md b/docs/src/gd/index.md
index e17afd7360bca5d5569e618a0a3c89fb6689e13a..08b037f5f9151efee4a8776ddda5aa760517206f 100644
--- a/docs/src/gd/index.md
+++ b/docs/src/gd/index.md
@@ -159,7 +159,7 @@ so that you can understand what actions will and will not be&nbsp;tolerated.
 
 ### Contributing guide
 
-Read our [contributing guide](../contributing/guidelines.md) to learn about our
+Read our [contributing guide](./contributing/guidelines.md) to learn about our
 development process, how to propose bugfixes and improvements, and how to build
 and test your changes to Castopod.
 
diff --git a/docs/src/sv/index.md b/docs/src/sv/index.md
index 9e2555f8f420057ab4f421044ba03727d4349ade..39b2617cdd467aa960bbc1da0ee0f516c361d5d5 100644
--- a/docs/src/sv/index.md
+++ b/docs/src/sv/index.md
@@ -22,7 +22,7 @@ mycket litet fotavtryck.
 - 🌱 &nbsp;Gratis & öppen källkod (AGPL v3-licens)
 - 🔐 &nbsp;Fokuserad på datasuveränitet: ditt innehåll, målgrupp och analys
   tillhör dig, och&nbsp;du&nbsp;bara
-- 🪄 &nbsp;Podcasting 2.0 funktioner: GUID, låst, avskrifter, finansiering,
+- <unk> &nbsp;Podcasting 2.0 funktioner: GUID, låst, avskrifter, finansiering,
   kapitel, plats, personer, ljud, …
 - 💬 &nbsp;Inbyggt socialt nätverk:
   - 🚀 &nbsp;Castopod är en del av Fediverse, ett decentraliserat socialt
@@ -30,7 +30,7 @@ mycket litet fotavtryck.
   - ❤️ &nbsp;Skapa inlägg, dela, favorit och kommentera avsnitt
 - 📈 &nbsp;Inbyggd analys:
   - ⚖️ &nbsp;GDPR / CCPA / LGPD kompatibel
-  - 🪙 &nbsp;Standard IABv2 målgruppsmätning
+  - <unk> &nbsp;Standard IABv2 målgruppsmätning
   - 🏡 &nbsp;Lokalanalys, ingen tredje part involverad
 - 📢 &nbsp;Inbyggda marknadsföringsverktyg:
   - ✅ &nbsp;SEO ready (open-graph meta-tags, JSON-LD, …)
@@ -38,7 +38,8 @@ mycket litet fotavtryck.
   - 🎨 &nbsp;Anpassningsbara temafärger
   - 🎬 &nbsp;Generera att dela videoklipp från avsnitt
   - 🔉 &nbsp;Generera ljudbitar
-  - ▶️ &nbsp;Inbäddbar spelare, bädda in dina avsnitt på valfri webbplats
+  - <unk> \_button_selector: &nbsp;Inbäddbar spelare, bädda in dina avsnitt på
+    valfri webbplats
 - 💸 &nbsp;Monetization:
   - 🔗 &nbsp;Finansierar länkar
   - 📲 &nbsp;lista-att-klicka annonser
@@ -50,7 +51,7 @@ mycket litet fotavtryck.
   - ⚡ &nbsp;Sänd dina avsnitt direkt med WebSub
 - 📥 &nbsp;Podcast import: flytta din befintliga podcast till Castopod
 - 📤 &nbsp;Flytta ut din podcast från Castopod
-- 🔀 &nbsp;Flera hyresgäst: värd så många podcasts du vill
+- :shuffle_tracks<unk> &nbsp;Flera hyresgäst: värd så många podcasts du vill
 - 👥 &nbsp;Flera användare: lägg till bidragslämnare och ange roller
 - 🌎 &nbsp;i18n support: översatt till engelska, franska, polska, tyska,
   brasilianska portugisiska & spanska… med
diff --git a/docs/src/uk/index.md b/docs/src/uk/index.md
index e17afd7360bca5d5569e618a0a3c89fb6689e13a..08b037f5f9151efee4a8776ddda5aa760517206f 100644
--- a/docs/src/uk/index.md
+++ b/docs/src/uk/index.md
@@ -159,7 +159,7 @@ so that you can understand what actions will and will not be&nbsp;tolerated.
 
 ### Contributing guide
 
-Read our [contributing guide](../contributing/guidelines.md) to learn about our
+Read our [contributing guide](./contributing/guidelines.md) to learn about our
 development process, how to propose bugfixes and improvements, and how to build
 and test your changes to Castopod.
 
diff --git a/docs/src/zh-Hans/getting-started/update.md b/docs/src/zh-Hans/getting-started/update.md
index 410d4193ab28ddc91c791ebf3be70be779c7f7f8..f8f7c4ef0f147796170e1ff0925be62e1a6adb26 100644
--- a/docs/src/zh-Hans/getting-started/update.md
+++ b/docs/src/zh-Hans/getting-started/update.md
@@ -53,8 +53,10 @@ sidebarDepth: 3
 [发布页面](https://code.castopod.org/adaures/castopod/-/releases))。
 
 - cf.
-  [我很长时间没有更新我的实例… 我该怎么办? 我该怎么办?](#我很长时间没有更新我的实例-我该怎么办-我该怎么办)
-  :::
+  [I haven't updated my instance in a long time… What should I do?](#i-havent-updated-my-instance-in-a-long-time-what-should-i-do)
+  我该怎么办?</a>
+
+:::
 
 ## 全自动更新
 
diff --git a/docs/src/zh-Hans/index.md b/docs/src/zh-Hans/index.md
index 3df1351239f334167b470dec490cb2c0a0789714..37d7c0516f09aba3d1ce6738745fa31906f451d8 100644
--- a/docs/src/zh-Hans/index.md
+++ b/docs/src/zh-Hans/index.md
@@ -154,8 +154,9 @@ so that you can understand what actions will and will not be&nbsp;tolerated.
 
 ### 贡献指南
 
-阅读我们的 [贡献指南](../contributing/guidelines.md) ,了解我们的开发过程。 提出
-错 误修正和改进想法,以及如何构建和测试 Castopod 。
+Read our [contributing guide](./contributing/guidelines.md) to learn about our
+development process, how to propose bugfixes and improvements, and how to build
+and test your changes to Castopod.
 
 ## 贡献者 ✨
 
diff --git a/modules/Admin/Language/ar/Episode.php b/modules/Admin/Language/ar/Episode.php
index 2c4319f80c5c47ca9803f338865345206253b70a..cac3ebd371f9389069ac27bd59e2745235cf6b05 100644
--- a/modules/Admin/Language/ar/Episode.php
+++ b/modules/Admin/Language/ar/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/br/Episode.php b/modules/Admin/Language/br/Episode.php
index 6c793ec9f2ce7a2074020ff314a1908aa4a91b11..cea956c58dc00ae7bd979bd898cef34560da859d 100644
--- a/modules/Admin/Language/br/Episode.php
+++ b/modules/Admin/Language/br/Episode.php
@@ -88,7 +88,7 @@ return [
             image {ar golo}
             audio {an aodio}
             other {ar media}
-        } ({file_key}). Gallout a rit lemel kuit ar restr-mañ diouzh ar gantenn dre zorn.',
+        } ({file_path}). Gallout a rit lemel kuit ar restr-mañ diouzh ar gantenn dre zorn.',
         'sameSlugError' => 'Bez ez eus eus ur rann gant ar berradur-mañ (slug) dija.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/ca/Episode.php b/modules/Admin/Language/ca/Episode.php
index c20eb8e8deafeaf113ee1c98f32256dc63b147d9..c80dc1d5334599625cfc89007667f4cc7f775226 100644
--- a/modules/Admin/Language/ca/Episode.php
+++ b/modules/Admin/Language/ca/Episode.php
@@ -80,7 +80,7 @@ return [
             audio {l\'àudio}
             other {el material}
         } de l\'episodi.',
-        'deleteFileError' => 'No s\'ha pogut esborrar el fitxer {file_key} {type, select,
+        'deleteFileError' => 'No s\'ha pogut esborrar el fitxer {file_path} {type, select,
             transcript {de la transcripció}
             chapters {dels episodis}
             image {de la portada}
diff --git a/modules/Admin/Language/de/Episode.php b/modules/Admin/Language/de/Episode.php
index 7b286fb8ab53a90d63c2690b79620300bf4c4497..ce77a865317ae7033e08f3ae91bc2e85ff5f32d3 100644
--- a/modules/Admin/Language/de/Episode.php
+++ b/modules/Admin/Language/de/Episode.php
@@ -86,7 +86,7 @@ return [
             image {Cover}
             audio {Audio}
             other {Medien}
-        }-Datei {file_key}. Sie können es manuell von der Festplatte entfernen.',
+        }-Datei {file_path}. Sie können es manuell von der Festplatte entfernen.',
         'sameSlugError' => 'Eine Folge mit dem ausgewählten Slug existiert bereits.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/el/Episode.php b/modules/Admin/Language/el/Episode.php
index fc9c0e927d9643feb11aa52de142ba9cf64611c3..2eeec1c35af4cba28aeb51ab4d0d932fab2385b0 100644
--- a/modules/Admin/Language/el/Episode.php
+++ b/modules/Admin/Language/el/Episode.php
@@ -86,7 +86,7 @@ return [
             image {καλύψτε}
             audio {ήχος}
             other {πολυμέσα}
-        } αρχείο {file_key}. Μπορείτε να το αφαιρέσετε χειροκίνητα από το δίσκο σας.',
+        } αρχείο {file_path}. Μπορείτε να το αφαιρέσετε χειροκίνητα από το δίσκο σας.',
         'sameSlugError' => 'Ένα επεισόδιο με το επιλεγμένο slug υπάρχει ήδη.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/fa/Episode.php b/modules/Admin/Language/fa/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/fa/Episode.php
+++ b/modules/Admin/Language/fa/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/fr/Episode.php b/modules/Admin/Language/fr/Episode.php
index 55579ee302ff7fa42de4e9f38539e0e711b00c88..83caff77886171bb6a1fa024fb07377992cc0fc8 100644
--- a/modules/Admin/Language/fr/Episode.php
+++ b/modules/Admin/Language/fr/Episode.php
@@ -86,7 +86,7 @@ return [
             image {couverture}
             audio {audio}
             other {média}
-        } fichier {file_key}. Vous pouvez le supprimer manuellement de votre disque.',
+        } fichier {file_path}. Vous pouvez le supprimer manuellement de votre disque.',
         'sameSlugError' => 'Il existe déjà un épisode avec le slug choisi.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/fr2/AboutCastopod.php b/modules/Admin/Language/fr2/AboutCastopod.php
new file mode 100644
index 0000000000000000000000000000000000000000..3fb62afffecaf7007a17da81fbcb6f96d1917c76
--- /dev/null
+++ b/modules/Admin/Language/fr2/AboutCastopod.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'title' => 'About Castopod',
+    'host_name' => 'Host name',
+    'version' => 'Castopod version',
+    'php_version' => 'PHP version',
+    'os' => 'Operating System',
+    'languages' => 'Languages',
+    'update_database' => 'Update database',
+    'messages' => [
+        'databaseUpdateSuccess' => 'Database is up to date!',
+    ],
+];
diff --git a/modules/Admin/Language/fr2/Dashboard.php b/modules/Admin/Language/fr2/Dashboard.php
new file mode 100644
index 0000000000000000000000000000000000000000..881073fd26316b7d2eda7c52b73ccbfc2c4e76e6
--- /dev/null
+++ b/modules/Admin/Language/fr2/Dashboard.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'home' => 'Admin dashboard',
+    'welcome_message' => 'Welcome to the admin area!',
+    'podcasts' => [
+        'title' => 'Podcasts',
+        'not_found' => 'No published podcast',
+        'last_published' => 'Last published on {lastPublicationDate}',
+    ],
+    'episodes' => [
+        'title' => 'Episodes',
+        'not_found' => 'No published episode',
+        'last_published' => 'Last published on {lastPublicationDate}',
+    ],
+    'storage' => [
+        'title' => 'Storage',
+        'subtitle' => '{totalUploaded} out of {totalStorage}',
+    ],
+];
diff --git a/modules/Admin/Language/fr2/Navigation.php b/modules/Admin/Language/fr2/Navigation.php
new file mode 100644
index 0000000000000000000000000000000000000000..610f14345d427177b5bcbea0b56c1f56512b70ff
--- /dev/null
+++ b/modules/Admin/Language/fr2/Navigation.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'toggle_sidebar' => 'Toggle sidebar',
+    'go_to_website' => 'Go to website',
+    'go_to_admin' => 'Go to admin',
+    'dashboard' => 'Dashboard',
+    'admin' => 'Home',
+    'podcasts' => 'Podcasts',
+    'podcast-list' => 'All podcasts',
+    'podcast-create' => 'New podcast',
+    'podcast-import' => 'Import a podcast',
+    'persons' => 'Persons',
+    'person-list' => 'All persons',
+    'person-create' => 'New person',
+    'fediverse' => 'Fediverse',
+    'fediverse-blocked-actors' => 'Blocked accounts',
+    'fediverse-blocked-domains' => 'Blocked domains',
+    'users' => 'Users',
+    'user-list' => 'All users',
+    'user-create' => 'New user',
+    'pages' => 'Pages',
+    'page-list' => 'All pages',
+    'page-create' => 'New Page',
+    'settings' => 'Settings',
+    'settings-general' => 'General',
+    'settings-theme' => 'Theme',
+    'about' => 'About',
+    'account' => [
+        'my-account' => 'My account',
+        'change-password' => 'Change password',
+        'logout' => 'Logout',
+    ],
+];
diff --git a/modules/Admin/Language/fr2/Notifications.php b/modules/Admin/Language/fr2/Notifications.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b139d51816866b727b96edd30a1a7b607aafb89
--- /dev/null
+++ b/modules/Admin/Language/fr2/Notifications.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'title' => 'Notifications',
+    'reply' => '{actor_username} replied to your post',
+    'favourite' => '{actor_username} favourited your post',
+    'reblog' => '{actor_username} shared your post',
+    'follow' => '{actor_username} started following you',
+    'no_notifications' => 'No notifications',
+    'mark_all_as_read' => 'Mark all as read',
+];
diff --git a/modules/Admin/Language/fr2/Page.php b/modules/Admin/Language/fr2/Page.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6f49de57496ec4830246641f0bf8897e7c9a2f9
--- /dev/null
+++ b/modules/Admin/Language/fr2/Page.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'back_to_home' => 'Back to home',
+    'page' => 'Page',
+    'all_pages' => 'All pages',
+    'create' => 'New page',
+    'go_to_page' => 'Go to page',
+    'edit' => 'Edit page',
+    'delete' => 'Delete page',
+    'form' => [
+        'title' => 'Title',
+        'permalink' => 'Permalink',
+        'content' => 'Content',
+        'submit_create' => 'Create page',
+        'submit_edit' => 'Save',
+    ],
+    'messages' => [
+        'createSuccess' => 'The page “{pageTitle}” was created successfully!',
+        'editSuccess' => 'The page was successfully updated!',
+    ],
+];
diff --git a/modules/Admin/Language/fr2/Pager.php b/modules/Admin/Language/fr2/Pager.php
new file mode 100644
index 0000000000000000000000000000000000000000..e25ee638108dba1e0bfa602b45969381dd8ebd57
--- /dev/null
+++ b/modules/Admin/Language/fr2/Pager.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'pageNavigation' => 'Page navigation',
+    'first' => 'First',
+    'previous' => 'Previous',
+    'next' => 'Next',
+    'last' => 'Last',
+    'older' => 'Older',
+    'newer' => 'Newer',
+    'invalidTemplate' => '{0} is not a valid Pager template.',
+    'invalidPaginationGroup' => '{0} is not a valid Pagination group.',
+];
diff --git a/modules/Admin/Language/fr2/Person.php b/modules/Admin/Language/fr2/Person.php
new file mode 100644
index 0000000000000000000000000000000000000000..a652be9fda1f4aeb73bcb01c35f13a452a6d4741
--- /dev/null
+++ b/modules/Admin/Language/fr2/Person.php
@@ -0,0 +1,65 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'persons' => 'Persons',
+    'all_persons' => 'All persons',
+    'no_person' => 'Nobody found!',
+    'create' => 'Create a person',
+    'view' => 'View person',
+    'edit' => 'Edit person',
+    'delete' => 'Delete person',
+    'messages' => [
+        'createSuccess' => 'Person has been successfully created!',
+        'editSuccess' => 'Person has been successfully updated!',
+        'deleteSuccess' => 'Person has been removed!',
+    ],
+    'form' => [
+        'avatar' => 'Avatar',
+        'avatar_size_hint' =>
+            'Avatar must be squared and at least 400px wide and tall.',
+        'full_name' => 'Full name',
+        'full_name_hint' => 'This is the full name or alias of the person.',
+        'unique_name' => 'Unique name',
+        'unique_name_hint' => 'Used for URLs',
+        'information_url' => 'Information URL',
+        'information_url_hint' =>
+            'Url to a relevant resource of information about the person, such as a homepage or third-party profile platform.',
+        'submit_create' => 'Create person',
+        'submit_edit' => 'Save person',
+    ],
+    'podcast_form' => [
+        'title' => 'Manage persons',
+        'add_section_title' => 'Add persons to this podcast',
+        'add_section_subtitle' => 'You may pick several persons and roles.',
+        'persons' => 'Persons',
+        'persons_hint' =>
+            'You may select one or several persons with the same roles. You need to create the persons first.',
+        'roles' => 'Roles',
+        'roles_hint' =>
+            'You may select none, one or several roles for a person.',
+        'submit_add' => 'Add person(s)',
+        'remove' => 'Remove',
+    ],
+    'episode_form' => [
+        'title' => 'Manage persons',
+        'add_section_title' => 'Add persons to this episode',
+        'add_section_subtitle' => 'You may pick several persons and roles.',
+        'persons' => 'Persons',
+        'persons_hint' =>
+            'You may select one or several persons with the same roles. You need to create the persons first.',
+        'roles' => 'Roles',
+        'roles_hint' =>
+            'You may select none, one or several roles for a person.',
+        'submit_add' => 'Add person(s)',
+        'remove' => 'Remove',
+    ],
+    'credits' => 'Credits',
+];
diff --git a/modules/Admin/Language/fr2/Platforms.php b/modules/Admin/Language/fr2/Platforms.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab17d5999b1626535499464902c12f5c3bcb7aa8
--- /dev/null
+++ b/modules/Admin/Language/fr2/Platforms.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'title' => 'Platforms',
+    'home_url' => 'Go to {platformName} website',
+    'submit_url' => 'Submit your podcast on {platformName}',
+    'visible' => 'Display in podcast homepage?',
+    'on_embed' => 'Display on embeddable player?',
+    'remove' => 'Remove {platformName}',
+    'submit' => 'Save',
+    'messages' => [
+        'updateSuccess' => 'Platform links have been successfully updated!',
+        'removeLinkSuccess' => 'The platform link has been removed.',
+        'removeLinkError' =>
+            'The platform link could not be removed. Try again.',
+    ],
+    'description' => [
+        'podcasting' => 'The podcast ID on this platform',
+        'social' => 'The podcast account ID on this platform',
+        'funding' => 'Call to action message',
+    ],
+];
diff --git a/modules/Admin/Language/fr2/Podcast.php b/modules/Admin/Language/fr2/Podcast.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d46aff53156ca301dceb74443d75da60e0cd6e7
--- /dev/null
+++ b/modules/Admin/Language/fr2/Podcast.php
@@ -0,0 +1,314 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'all_podcasts' => 'All podcasts',
+    'no_podcast' => 'No podcast found!',
+    'create' => 'Create podcast',
+    'import' => 'Import podcast',
+    'new_episode' => 'New Episode',
+    'view' => 'View podcast',
+    'edit' => 'Edit podcast',
+    'publish' => 'Publish podcast',
+    'publish_edit' => 'Edit publication',
+    'delete' => 'Delete podcast',
+    'see_episodes' => 'See episodes',
+    'see_contributors' => 'See contributors',
+    'go_to_page' => 'Go to page',
+    'latest_episodes' => 'Latest episodes',
+    'see_all_episodes' => 'See all episodes',
+    'draft' => 'Draft',
+    'messages' => [
+        'createSuccess' => 'Podcast successfully created!',
+        'editSuccess' => 'Podcast has been successfully updated!',
+        'importSuccess' => 'Podcast has been successfully imported!',
+        'deleteSuccess' => 'Podcast @{podcast_handle} successfully deleted!',
+        'deletePodcastMediaError' => 'Failed to delete podcast {type, select,
+            cover {cover}
+            banner {banner}
+            other {media}
+        }.',
+        'deleteEpisodeMediaError' => 'Failed to delete podcast episode {episode_slug} {type, select,
+            transcript {transcript}
+            chapters {chapters}
+            image {cover}
+            audio {audio}
+            other {media}
+        }.',
+        'deletePodcastMediaFolderError' => 'Failed to delete podcast media folder {folder_path}. You may manually remove it from your disk.',
+        'podcastFeedUpdateSuccess' => 'Successful update: {number_of_new_episodes, plural,
+            one {# episode was}
+            other {# episodes were}
+        } added to the podcast!',
+        'podcastFeedUpToDate' => 'Podcast is already up to date.',
+        'podcastNotImported' => 'Podcast could not be updated as it was not imported.',
+        'publishError' => 'This podcast is either already published or scheduled for publication.',
+        'publishEditError' => 'This podcast is not scheduled for publication.',
+        'publishCancelSuccess' => 'Podcast publication successfully cancelled!',
+        'scheduleDateError' => 'Schedule date must be set!',
+    ],
+    'form' => [
+        'identity_section_title' => 'Podcast identity',
+        'identity_section_subtitle' => 'These fields allow you to get noticed.',
+        'cover' => 'Podcast cover',
+        'cover_size_hint' => 'Cover must be squared and at least 1400px wide and tall.',
+        'banner' => 'Podcast banner',
+        'banner_size_hint' => 'Banner must have a 3:1 ratio and be at least 1500px wide.',
+        'banner_delete' => 'Delete podcast banner',
+        'title' => 'Title',
+        'handle' => 'Handle',
+        'handle_hint' =>
+            'Used to identify the podcast. Uppercase, lowercase, numbers and underscores are accepted.',
+        'type' => [
+            'label' => 'Type',
+            'episodic' => 'Episodic',
+            'episodic_hint' => 'If episodes are intended to be consumed without any specific order. Newest episodes will be presented first.',
+            'serial' => 'Serial',
+            'serial_hint' => 'If episodes are intended to be consumed in sequential order. The oldest episodes will be presented first.',
+        ],
+        'description' => 'Description',
+        'classification_section_title' => 'Classification',
+        'classification_section_subtitle' =>
+            'These fields will impact your audience and competition.',
+        'language' => 'Language',
+        'category' => 'Category',
+        'category_placeholder' => 'Select a category…',
+        'other_categories' => 'Other categories',
+        'parental_advisory' => [
+            'label' => 'Parental advisory',
+            'hint' => 'Does it contain explicit content?',
+            'undefined' => 'undefined',
+            'clean' => 'Clean',
+            'explicit' => 'Explicit',
+        ],
+        'author_section_title' => 'Author',
+        'author_section_subtitle' => 'Who is managing the podcast?',
+        'owner_name' => 'Owner name',
+        'owner_name_hint' =>
+            'For administrative use only. Visible in the public RSS feed.',
+        'owner_email' => 'Owner email',
+        'owner_email_hint' =>
+            'Will be used by most platforms to verify the podcast ownership. Visible in the public RSS feed.',
+        'publisher' => 'Publisher',
+        'publisher_hint' =>
+            'The group responsible for creating the show. Often refers to the parent company or network of a podcast. This field is sometimes labeled as ’Author’.',
+        'copyright' => 'Copyright',
+        'location_section_title' => 'Location',
+        'location_section_subtitle' => 'What place is this podcast about?',
+        'location_name' => 'Location name or address',
+        'location_name_hint' => 'This can be a real place or fictional',
+        'monetization_section_title' => 'Monetization',
+        'monetization_section_subtitle' =>
+            'Earn money thanks to your audience.',
+        'premium' => 'Premium',
+        'premium_by_default' => 'Episodes must be set as premium by default',
+        'premium_by_default_hint' => 'Podcast episodes will be marked as premium by default. You can still choose to set some episodes, trailers or bonuses as public.',
+        'op3' => 'Open Podcast Prefix Project (OP3)',
+        'op3_hint' => 'Value your analytics data with OP3, an open-source and trusted third party analytics service. Share, validate and compare your analytics data with the open podcasting ecosystem.',
+        'op3_enable' => 'Enable OP3 analytics service',
+        'op3_enable_hint' => 'For security reasons, premium episodes\' analytics data will not be shared with OP3.',
+        'payment_pointer' => 'Payment Pointer for Web Monetization',
+        'payment_pointer_hint' =>
+            'This is your where you will receive money thanks to Web Monetization',
+        'advanced_section_title' => 'Advanced Parameters',
+        'advanced_section_subtitle' =>
+            'If you need RSS tags that Castopod does not handle, set them here.',
+        'custom_rss' => 'Custom RSS tags for the podcast',
+        'custom_rss_hint' => 'This will be injected within the ❬channel❭ tag.',
+        'new_feed_url' => 'New feed URL',
+        'new_feed_url_hint' => 'Use this field when you move to another domain or podcast hosting platform. By default, the value is set to the current RSS URL if the podcast is imported.',
+        'old_feed_url' => 'Old feed URL',
+        'update_feed' => 'Update feed',
+        'update_feed_tip' => 'Import this podcast\'s latest episodes',
+        'partnership' => 'Partnership',
+        'partner_id' => 'ID',
+        'partner_link_url' => 'Link URL',
+        'partner_image_url' => 'Image URL',
+        'partner_id_hint' => 'Your own partner ID',
+        'partner_link_url_hint' => 'The generic partner link address',
+        'partner_image_url_hint' => 'The generic partner image address',
+        'status_section_title' => 'Status',
+        'block' => 'Podcast should be hidden from public catalogues',
+        'block_hint' =>
+            'The podcast show or hide status: toggling this on prevents the entire podcast from appearing in Apple Podcasts, Google Podcasts, and any third party apps that pull shows from these directories. (Not guaranteed)',
+        'complete' => 'Podcast will not be having new episodes',
+        'lock' => 'Prevent podcast from being copied',
+        'lock_hint' =>
+            'The purpose is to tell other podcast platforms whether they are allowed to import this feed. A value of yes means that any attempt to import this feed into a new platform should be rejected.',
+        'submit_create' => 'Create podcast',
+        'submit_edit' => 'Save podcast',
+    ],
+    'category_options' => [
+        'uncategorized' => 'uncategorized',
+        'arts' => 'Arts',
+        'business' => 'Business',
+        'comedy' => 'Comedy',
+        'education' => 'Education',
+        'fiction' => 'Fiction',
+        'government' => 'Government',
+        'health_and_fitness' => 'Health &amp Fitness',
+        'history' => 'History',
+        'kids_and_family' => 'Kids &amp Family',
+        'leisure' => 'Leisure',
+        'music' => 'Music',
+        'news' => 'News',
+        'religion_and_spirituality' => 'Religion &amp Spirituality',
+        'science' => 'Science',
+        'society_and_culture' => 'Society &amp Culture',
+        'sports' => 'Sports',
+        'technology' => 'Technology',
+        'true_crime' => 'True Crime',
+        'tv_and_film' => 'TV &amp Film',
+        'books' => 'Books',
+        'design' => 'Design',
+        'fashion_and_beauty' => 'Fashion &amp Beauty',
+        'food' => 'Food',
+        'performing_arts' => 'Performing Arts',
+        'visual_arts' => 'Visual Arts',
+        'careers' => 'Careers',
+        'entrepreneurship' => 'Entrepreneurship',
+        'investing' => 'Investing',
+        'management' => 'Management',
+        'marketing' => 'Marketing',
+        'non_profit' => 'Non-Profit',
+        'comedy_interviews' => 'Comedy Interviews',
+        'improv' => 'Improv',
+        'stand_up' => 'Stand-Up',
+        'courses' => 'Courses',
+        'how_to' => 'How To',
+        'language_learning' => 'Language Learning',
+        'self_improvement' => 'Self-Improvement',
+        'comedy_fiction' => 'Comedy Fiction',
+        'drama' => 'Drama',
+        'science_fiction' => 'Science Fiction',
+        'alternative_health' => 'Alternative Health',
+        'fitness' => 'Fitness',
+        'medicine' => 'Medicine',
+        'mental_health' => 'Mental Health',
+        'nutrition' => 'Nutrition',
+        'sexuality' => 'Sexuality',
+        'education_for_kids' => 'Education for Kids',
+        'parenting' => 'Parenting',
+        'pets_and_animals' => 'Pets &amp Animals',
+        'stories_for_kids' => 'Stories for Kids',
+        'animation_and_manga' => 'Animation &amp Manga',
+        'automotive' => 'Automotive',
+        'aviation' => 'Aviation',
+        'crafts' => 'Crafts',
+        'games' => 'Games',
+        'hobbies' => 'Hobbies',
+        'home_and_garden' => 'Home &amp Garden',
+        'video_games' => 'Video Games',
+        'music_commentary' => 'Music Commentary',
+        'music_history' => 'Music History',
+        'music_interviews' => 'Music Interviews',
+        'business_news' => 'Business News',
+        'daily_news' => 'Daily News',
+        'entertainment_news' => 'Entertainment News',
+        'news_commentary' => 'News Commentary',
+        'politics' => 'Politics',
+        'sports_news' => 'Sports News',
+        'tech_news' => 'Tech News',
+        'buddhism' => 'Buddhism',
+        'christianity' => 'Christianity',
+        'hinduism' => 'Hinduism',
+        'islam' => 'Islam',
+        'judaism' => 'Judaism',
+        'religion' => 'Religion',
+        'spirituality' => 'Spirituality',
+        'astronomy' => 'Astronomy',
+        'chemistry' => 'Chemistry',
+        'earth_sciences' => 'Earth Sciences',
+        'life_sciences' => 'Life Sciences',
+        'mathematics' => 'Mathematics',
+        'natural_sciences' => 'Natural Sciences',
+        'nature' => 'Nature',
+        'physics' => 'Physics',
+        'social_sciences' => 'Social Sciences',
+        'documentary' => 'Documentary',
+        'personal_journals' => 'Personal Journals',
+        'philosophy' => 'Philosophy',
+        'places_and_travel' => 'Places &amp Travel',
+        'relationships' => 'Relationships',
+        'baseball' => 'Baseball',
+        'basketball' => 'Basketball',
+        'cricket' => 'Cricket',
+        'fantasy_sports' => 'Fantasy Sports',
+        'football' => 'Football',
+        'golf' => 'Golf',
+        'hockey' => 'Hockey',
+        'rugby' => 'Rugby',
+        'running' => 'Running',
+        'soccer' => 'Soccer',
+        'swimming' => 'Swimming',
+        'tennis' => 'Tennis',
+        'volleyball' => 'Volleyball',
+        'wilderness' => 'Wilderness',
+        'wrestling' => 'Wrestling',
+        'after_shows' => 'After Shows',
+        'film_history' => 'Film History',
+        'film_interviews' => 'Film Interviews',
+        'film_reviews' => 'Film Reviews',
+        'tv_reviews' => 'TV Reviews',
+    ],
+    'publish_form' => [
+        'back_to_podcast_dashboard' => 'Back to podcast dashboard',
+        'post' => 'Your announcement post',
+        'post_hint' =>
+            "Write a message to announce the publication of your podcast. The message will be featured in your podcast's homepage.",
+        'message_placeholder' => 'Write your message…',
+        'submit' => 'Publish',
+        'publication_date' => 'Publication date',
+        'publication_method' => [
+            'now' => 'Now',
+            'schedule' => 'Schedule',
+        ],
+        'scheduled_publication_date' => 'Scheduled publication date',
+        'scheduled_publication_date_hint' =>
+            'You can schedule the podcast release by setting a future publication date. This field must be formatted as YYYY-MM-DD HH:mm',
+        'submit_edit' => 'Edit publication',
+        'cancel_publication' => 'Cancel publication',
+        'message_warning' => 'You did not write a message for your announcement post!',
+        'message_warning_hint' => 'Having a message increases social engagement, resulting in a better visibility for your podcast.',
+        'message_warning_submit' => 'Publish anyway',
+    ],
+    'publication_status_banner' => [
+        'draft_mode' => 'draft mode',
+        'not_published' => 'This podcast is not yet published.',
+        'scheduled' => 'This podcast is scheduled for publication on {publication_date}.',
+    ],
+    'delete_form' => [
+        'disclaimer' =>
+            "Deleting the podcast will delete all episodes, media files, posts and analytics associated with it. This action is irreversible, you will not be able to retrieve them afterwards.",
+        'understand' => 'I understand, I want the podcast to be permanently deleted',
+        'submit' => 'Delete',
+    ],
+    'by' => 'By {publisher}',
+    'season' => 'Season {seasonNumber}',
+    'list_of_episodes_year' => '{year} episodes ({episodeCount})',
+    'list_of_episodes_season' =>
+        'Season {seasonNumber} episodes ({episodeCount})',
+    'no_episode' => 'No episode found!',
+    'follow' => 'Follow',
+    'followers' => '{numberOfFollowers, plural,
+        one {# follower}
+        other {# followers}
+    }',
+    'posts' => '{numberOfPosts, plural,
+        one {# post}
+        other {# posts}
+    }',
+    'activity' => 'Activity',
+    'episodes' => 'Episodes',
+    'sponsor' => 'Sponsor',
+    'funding_links' => 'Funding links for {podcastTitle}',
+    'find_on' => 'Find {podcastTitle} on',
+    'listen_on' => 'Listen on',
+];
diff --git a/modules/Admin/Language/fr2/PodcastImport.php b/modules/Admin/Language/fr2/PodcastImport.php
new file mode 100644
index 0000000000000000000000000000000000000000..7c3ef67d1f998b7f3d7e5d658d2ae7b99851f4f5
--- /dev/null
+++ b/modules/Admin/Language/fr2/PodcastImport.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'warning' =>
+        'This procedure may take a long time. As the current version does not show any progress while it runs, you will not see anything updated until it is done. In case of timeout error, increase `max_execution_time` value.',
+    'old_podcast_section_title' => 'The podcast to import',
+    'old_podcast_section_subtitle' =>
+        'Make sure you own the rights for this podcast before importing it. Copying and broadcasting a podcast without the proper rights is piracy and is liable to prosecution.',
+    'imported_feed_url' => 'Feed URL',
+    'imported_feed_url_hint' => 'The feed must be in xml or rss format.',
+    'new_podcast_section_title' => 'The new podcast',
+    'advanced_params_section_title' => 'Advanced parameters',
+    'advanced_params_section_subtitle' =>
+        'Keep the default values if you have no idea of what the fields are for.',
+    'slug_field' => 'Field to be used to calculate episode slug',
+    'description_field' =>
+        'Source field used for episode description / show notes',
+    'force_renumber' => 'Force episodes renumbering',
+    'force_renumber_hint' =>
+        'Use this if your podcast does not have episode numbers but wish to set them during import.',
+    'season_number' => 'Season number',
+    'season_number_hint' =>
+        'Use this if your podcast does not have a season number but wish to set one during import. Leave blank otherwise.',
+    'max_episodes' => 'Maximum number of episodes to import',
+    'max_episodes_hint' => 'Leave blank to import all episodes',
+    'lock_import' =>
+        'This feed is protected. You cannot import it. If you are the owner, unprotect it on the origin platform.',
+    'submit' => 'Import podcast',
+];
diff --git a/modules/Admin/Language/fr2/PodcastNavigation.php b/modules/Admin/Language/fr2/PodcastNavigation.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4d7ddc0899ebd78178fd75359ca189cd947dc52
--- /dev/null
+++ b/modules/Admin/Language/fr2/PodcastNavigation.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'go_to_page' => 'Go to podcast page',
+    'dashboard' => 'Podcast dashboard',
+    'podcast-view' => 'Home',
+    'podcast-edit' => 'Edit podcast',
+    'podcast-persons-manage' => 'Manage persons',
+    'episodes' => 'Episodes',
+    'episode-list' => 'All episodes',
+    'episode-create' => 'New episode',
+    'analytics' => 'Analytics',
+    'podcast-analytics' => 'Audience overview',
+    'podcast-analytics-webpages' => 'Web pages visits',
+    'podcast-analytics-locations' => 'Locations',
+    'podcast-analytics-unique-listeners' => 'Unique listeners',
+    'podcast-analytics-players' => 'Players',
+    'podcast-analytics-listening-time' => 'Listening time',
+    'podcast-analytics-time-periods' => 'Time periods',
+    'premium' => 'Premium',
+    'subscription-list' => 'All subscriptions',
+    'subscription-add' => 'Add subscription',
+    'contributors' => 'Contributors',
+    'contributor-list' => 'All contributors',
+    'contributor-add' => 'Add contributor',
+    'platforms' => 'External platforms',
+    'platforms-podcasting' => 'Podcasting',
+    'platforms-social' => 'Social networks',
+    'platforms-funding' => 'Funding',
+];
diff --git a/modules/Admin/Language/fr2/Settings.php b/modules/Admin/Language/fr2/Settings.php
new file mode 100644
index 0000000000000000000000000000000000000000..4a70dcbaa07478e928ece0f8f3ff501b93bd4312
--- /dev/null
+++ b/modules/Admin/Language/fr2/Settings.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'title' => 'General settings',
+    'instance' => [
+        'title' => 'Instance',
+        'site_icon' => 'Site icon',
+        'site_icon_delete' => 'Delete site icon',
+        'site_icon_hint' => 'Site icons are what you see on your browser tabs, bookmarks bar, and when you add a website as a shortcut on mobile devices.',
+        'site_icon_helper' => 'Icon must be squared and at least 512px wide and tall.',
+        'site_name' => 'Site name',
+        'site_description' => 'Site description',
+        'submit' => 'Save',
+        'editSuccess' => 'Instance has been updated successfully!',
+        'deleteIconSuccess' => 'Site icon has been remove successfully!',
+    ],
+    'images' => [
+        'title' => 'Images',
+        'subtitle' => 'Here you can regenerate all images based on the originals that were uploaded. To be used if you find that some images are missing. This task may take a while.',
+        'regenerate' => 'Regenerate images',
+        'regenerationSuccess' => 'All images have been regenerated successfully!',
+    ],
+    'housekeeping' => [
+        'title' => 'Housekeeping',
+        'subtitle' => 'Runs various housekeeping tasks. Use this feature if you ever encounter issues with media files or data integrity. These tasks may take a while.',
+        'reset_counts' => 'Reset counts',
+        'reset_counts_helper' => 'This option will recalculate and reset all data counts (number of followers, posts, comments, …).',
+        'rewrite_media' => 'Rewrite media metadata',
+        'rewrite_media_helper' => 'This option will delete all superfluous media files and recreate them (images, audio files, transcripts, chapters, …)',
+        'rename_episodes_files' => 'Rename episode audio files',
+        'rename_episodes_files_hint' => 'This option will rename all episodes audio files to a random string of characters. Use this if one of your private episodes link was leaked as this will effectively hide it.',
+        'clear_cache' => 'Clear all cache',
+        'clear_cache_helper' => 'This option will flush redis cache or writable/cache files.',
+        'run' => 'Run housekeeping',
+        'runSuccess' => 'Housekeeping has been run successfully!',
+    ],
+    'theme' => [
+        'title' => 'Theme',
+        'accent_section_title' => 'Accent color',
+        'accent_section_subtitle' => 'Choose the color to determine the look and feel of all public pages.',
+        'pine' => 'Pine',
+        'crimson' => 'Crimson',
+        'amber' => 'Amber',
+        'lake' => 'Lake',
+        'jacaranda' => 'Jacaranda',
+        'onyx' => 'Onyx',
+        'submit' => 'Save',
+        'setInstanceThemeSuccess' => 'Theme has been updated successfully!',
+    ],
+];
diff --git a/modules/Admin/Language/fr2/Soundbite.php b/modules/Admin/Language/fr2/Soundbite.php
new file mode 100644
index 0000000000000000000000000000000000000000..a3f828fe09fa68f902251e7438bb54a2727ac8cb
--- /dev/null
+++ b/modules/Admin/Language/fr2/Soundbite.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2021 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'list' => [
+        'title' => 'Soundbites',
+        'soundbite' => 'Soundbite',
+    ],
+    'messages' => [
+        'createSuccess' => 'Soundbite has been successfully created!',
+        'deleteSuccess' => 'Soundbite has been successfully removed!',
+    ],
+    'form' => [
+        'title' => 'New soundbite',
+        'soundbite_title' => 'Soundbite title',
+        'start_time' => 'Start at',
+        'duration' => 'Duration',
+        'submit' => 'Create soundbite',
+    ],
+    'play' => 'Play soundbite',
+    'stop' => 'Stop soundbite',
+    'create' => 'New soundbite',
+    'delete' => 'Delete soundbite',
+];
diff --git a/modules/Admin/Language/fr2/Validation.php b/modules/Admin/Language/fr2/Validation.php
new file mode 100644
index 0000000000000000000000000000000000000000..3bc78cfe1807ca1f3a2565e16a996b4b9d484ef8
--- /dev/null
+++ b/modules/Admin/Language/fr2/Validation.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'min_dims' =>
+        '{field} is either not an image, or it is not wide or tall enough.',
+    'is_image_ratio' =>
+        '{field} is either not an image or not of the right ratio.',
+];
diff --git a/modules/Admin/Language/fr2/VideoClip.php b/modules/Admin/Language/fr2/VideoClip.php
new file mode 100644
index 0000000000000000000000000000000000000000..638de697bba7f2c0fbc240dace9dd73bfeb77615
--- /dev/null
+++ b/modules/Admin/Language/fr2/VideoClip.php
@@ -0,0 +1,72 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2021 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'list' => [
+        'title' => 'Video clips',
+        'status' => [
+            'label' => 'Status',
+            'queued' => 'queued',
+            'queued_hint' => 'Clip is waiting to be processed.',
+            'pending' => 'pending',
+            'pending_hint' => 'Clip will be generated shortly.',
+            'running' => 'running',
+            'running_hint' => 'Clip is being generated.',
+            'failed' => 'failed',
+            'failed_hint' => 'Clip could not be generated: script failure.',
+            'passed' => 'passed',
+            'passed_hint' => 'Clip was generated successfully!',
+        ],
+        'clip' => 'Clip',
+        'duration' => 'Job duration',
+    ],
+    'title' => 'Video clip: {videoClipLabel}',
+    'download_clip' => 'Download clip',
+    'create' => 'New video clip',
+    'go_to_page' => 'Go to clip page',
+    'retry' => 'Retry clip generation',
+    'delete' => 'Delete clip',
+    'logs' => 'Job logs',
+    'messages' => [
+        'alreadyExistingError' => 'The video clip you are trying to create already exists!',
+        'addToQueueSuccess' => 'Video clip has been added to queue, awaiting to be created!',
+        'deleteSuccess' => 'Video clip has been successfully removed!',
+    ],
+    'format' => [
+        'landscape' => 'Landscape',
+        'portrait' => 'Portrait',
+        'squared' => 'Squared',
+    ],
+    'form' => [
+        'title' => 'New video clip',
+        'params_section_title' => 'Video clip parameters',
+        'clip_title' => 'Clip title',
+        'format' => [
+            'label' => 'Choose a format',
+            'landscape_hint' => 'With a 16:9 ratio, landscape videos are great for PeerTube, Youtube and Vimeo.',
+            'portrait_hint' => 'With a 9:16 ratio, portrait videos are great for TikTok, Youtube shorts and Instagram stories.',
+            'squared_hint' => 'With a 1:1 ratio, squared videos are great for Mastodon, Facebook, Twitter and LinkedIn.',
+        ],
+        'theme' => 'Select a theme',
+        'start_time' => 'Start at',
+        'duration' => 'Duration',
+        'trim_start' => 'Trim start',
+        'trim_end' => 'Trim end',
+        'submit' => 'Create video clip',
+    ],
+    'requirements' => [
+        'title' => 'Missing requirements',
+        'missing' => 'You have missing requirements. Make sure to add all the required items to be allowed creating a video for this episode!',
+        'ffmpeg' => 'FFmpeg',
+        'gd' => 'Graphics Draw (GD)',
+        'freetype' => 'Freetype library for GD',
+        'transcript' => 'Transcript file (.srt)',
+    ],
+];
diff --git a/modules/Admin/Language/gd/Episode.php b/modules/Admin/Language/gd/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/gd/Episode.php
+++ b/modules/Admin/Language/gd/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/gl/Episode.php b/modules/Admin/Language/gl/Episode.php
index 3d7c5c7688b71e5bb08a203ea136229e4ac9a1c8..428610bc24cc659f56702337e5df8bff747ddf6a 100644
--- a/modules/Admin/Language/gl/Episode.php
+++ b/modules/Admin/Language/gl/Episode.php
@@ -86,7 +86,7 @@ return [
             image {da imaxe}
             audio {do audio}
             other {do multimedia}
-        } {file_key}. Deberías eliminala manualmente do disco.',
+        } {file_path}. Deberías eliminala manualmente do disco.',
         'sameSlugError' => 'Xa existe un episodio co id de url elexido.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/id/Episode.php b/modules/Admin/Language/id/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/id/Episode.php
+++ b/modules/Admin/Language/id/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/it/Episode.php b/modules/Admin/Language/it/Episode.php
index a05f6147ca78267f52ac2a817a3b596c05d27e9e..56151df784e8368da0bf09c86f88aef957fddac4 100644
--- a/modules/Admin/Language/it/Episode.php
+++ b/modules/Admin/Language/it/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/ko/Episode.php b/modules/Admin/Language/ko/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/ko/Episode.php
+++ b/modules/Admin/Language/ko/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/nl/Episode.php b/modules/Admin/Language/nl/Episode.php
index ffd05f72aee1828b76e6bd1a4984c25c79e1f1d6..9902c773707830a345b5e45015b3204978366147 100644
--- a/modules/Admin/Language/nl/Episode.php
+++ b/modules/Admin/Language/nl/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/nn-NO/Episode.php b/modules/Admin/Language/nn-NO/Episode.php
index cbd0205512ce644f6f0101d4386b98aaa209b1a8..2389cec9d4440fbe773201687212b9b8428f511e 100644
--- a/modules/Admin/Language/nn-NO/Episode.php
+++ b/modules/Admin/Language/nn-NO/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/oc/Episode.php b/modules/Admin/Language/oc/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/oc/Episode.php
+++ b/modules/Admin/Language/oc/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/pl/Episode.php b/modules/Admin/Language/pl/Episode.php
index 2527d37faa7fd978f0e715f3cb5af880058eced8..e58524c063ad01cb42b7a76baf77acafab30046d 100644
--- a/modules/Admin/Language/pl/Episode.php
+++ b/modules/Admin/Language/pl/Episode.php
@@ -88,7 +88,7 @@ return [
             image {okładka}
             audio {audio}
             other {media}
-        } plik {file_key}. Możesz ręcznie usunąć go ze swojego dysku.',
+        } plik {file_path}. Możesz ręcznie usunąć go ze swojego dysku.',
         'sameSlugError' => 'Odcinek z wybranym slugiem już istnieje.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/pt-BR/Episode.php b/modules/Admin/Language/pt-BR/Episode.php
index 9d468743256e09b49b8e00e25251ffdf692d51a5..ad8e65104aeda8192c94d24dc63b7a650e4e1104 100644
--- a/modules/Admin/Language/pt-BR/Episode.php
+++ b/modules/Admin/Language/pt-BR/Episode.php
@@ -86,7 +86,7 @@ return [
             image {capa}
             audio {áudio}
             other {mídia}
-        } {file_key}. Você pode removê-lo manualmente do seu disco.',
+        } {file_path}. Você pode removê-lo manualmente do seu disco.',
         'sameSlugError' => 'Um episódio com o slug escolhido já existe.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/pt/Episode.php b/modules/Admin/Language/pt/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/pt/Episode.php
+++ b/modules/Admin/Language/pt/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/ro/Episode.php b/modules/Admin/Language/ro/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/ro/Episode.php
+++ b/modules/Admin/Language/ro/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/ru/Episode.php b/modules/Admin/Language/ru/Episode.php
index 5ed5e3acef257e6d98f03cb839353c24398c5e5c..98498bee2185428d4ca8a5763c651eab250e53d5 100644
--- a/modules/Admin/Language/ru/Episode.php
+++ b/modules/Admin/Language/ru/Episode.php
@@ -86,7 +86,7 @@ return [
             image {cover}
             audio {audio}
             other {media}
-        } file {file_key}. You may manually remove it from your disk.',
+        } file {file_path}. You may manually remove it from your disk.',
         'sameSlugError' => 'An episode with the chosen slug already exists.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/sk/Episode.php b/modules/Admin/Language/sk/Episode.php
index 58531d51b65ebb4488f6579390aa8fa2233b3d9b..e1894d11687260433a94e18314a61972666bfd32 100644
--- a/modules/Admin/Language/sk/Episode.php
+++ b/modules/Admin/Language/sk/Episode.php
@@ -90,7 +90,7 @@ return [
             image {obrázok}
             audio {zvuk}
             other {médiá}
-        } súbor {file_key}. Môžete ho z disku odstrániť ručne.',
+        } súbor {file_path}. Môžete ho z disku odstrániť ručne.',
         'sameSlugError' => 'Epizóda s takýmto trvalým odkazom už existuje.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/sr_Latn/Episode.php b/modules/Admin/Language/sr_Latn/Episode.php
index c38350a6d11b2e463a9d711e06dd515ce967e818..d06b5d04d41f03459e9b158a6782999c510d801d 100644
--- a/modules/Admin/Language/sr_Latn/Episode.php
+++ b/modules/Admin/Language/sr_Latn/Episode.php
@@ -86,7 +86,7 @@ return [
             image {omota}
             audio {zvuka}
             other {medija}
-        } datoteke {file_key}. Možete je ukloniti ručno sa diska.',
+        } datoteke {file_path}. Možete je ukloniti ručno sa diska.',
         'sameSlugError' => 'Odabrano URL ime (slug) epizode već postoji.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/sv/Episode.php b/modules/Admin/Language/sv/Episode.php
index b289b8df2e0812a8e4c8abce8116165ce3bc907e..542449f157cb747da89b17e87c88e7e01bf5ec0f 100644
--- a/modules/Admin/Language/sv/Episode.php
+++ b/modules/Admin/Language/sv/Episode.php
@@ -86,7 +86,7 @@ return [
             image {omslag}
             audio {ljud}
             other {media}
-        } fil {file_key}. Du kan manuellt ta bort den från disken.',
+        } fil {file_path}. Du kan manuellt ta bort den från disken.',
         'sameSlugError' => 'Ett avsnitt med den valda slug finns redan.',
     ],
     'form' => [
diff --git a/modules/Admin/Language/zh-Hans/Episode.php b/modules/Admin/Language/zh-Hans/Episode.php
index 3c0afc818fa23b6fd28032dde9df42ba7face042..6205a818dd430d8dd951d3296bc7fecf34357a2f 100644
--- a/modules/Admin/Language/zh-Hans/Episode.php
+++ b/modules/Admin/Language/zh-Hans/Episode.php
@@ -86,7 +86,7 @@ return [
             image {封面}
             audio {音频}
             other {媒体}
-        } 文件 {file_key}。您可以手动将其从磁盘删除。',
+        } 文件 {file_path}。您可以手动将其从磁盘删除。',
         'sameSlugError' => '选中的剧集已存在。',
     ],
     'form' => [
diff --git a/modules/Auth/Language/fr2/Auth.php b/modules/Auth/Language/fr2/Auth.php
new file mode 100644
index 0000000000000000000000000000000000000000..a47932e31797e06003e4d4cb94e6e824cb053a12
--- /dev/null
+++ b/modules/Auth/Language/fr2/Auth.php
@@ -0,0 +1,94 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2022 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'instance_groups' => [
+        'owner' => [
+            'title' => 'Instance Owner',
+            'description' => 'The Castopod owner.',
+        ],
+        'superadmin' => [
+            'title' => 'Super admin',
+            'description' => 'Has complete control over Castopod.',
+        ],
+        'manager' => [
+            'title' => 'Manager',
+            'description' => 'Manages Castopod\'s content.',
+        ],
+        'podcaster' => [
+            'title' => 'Podcaster',
+            'description' => 'General users of Castopod.',
+        ],
+    ],
+    'instance_permissions' => [
+        'admin.access' => 'Can access the Castopod admin area.',
+        'admin.settings' => 'Can access the Castopod settings.',
+        'users.manage' => 'Can manage Castopod users.',
+        'persons.manage' => 'Can manage persons.',
+        'pages.manage' => 'Can manage pages.',
+        'podcasts.view' => 'Can view all podcasts.',
+        'podcasts.create' => 'Can create new podcasts.',
+        'podcasts.import' => 'Can import podcasts.',
+        'fediverse.manage-blocks' => 'Can block fediverse actors/domains from interacting with Castopod.',
+    ],
+    'podcast_groups' => [
+        'owner' => [
+            'title' => 'Podcast Owner',
+            'description' => 'The podcast owner.',
+        ],
+        'admin' => [
+            'title' => 'Admin',
+            'description' => 'Has complete control of podcast #{id}.',
+        ],
+        'editor' => [
+            'title' => 'Editor',
+            'description' => 'Manages content and publications of podcast #{id}.',
+        ],
+        'author' => [
+            'title' => 'Author',
+            'description' => 'Manages content of podcast #{id} but cannot publish them.',
+        ],
+        'guest' => [
+            'title' => 'Guest',
+            'description' => 'General contributor of the podcast #{id}.',
+        ],
+    ],
+    'podcast_permissions' => [
+        'view' => 'Can view dashboard and analytics of podcast #{id}.',
+        'edit' => 'Can edit podcast #{id}.',
+        'delete' => 'Can delete podcast #{id}.',
+        'manage-import' => 'Can synchronize imported podcast #{id}.',
+        'manage-persons' => 'Can manage subscriptions of podcast #{id}.',
+        'manage-subscriptions' => 'Can manage subscriptions of podcast #{id}.',
+        'manage-contributors' => 'Can manage contributors of podcast #{id}.',
+        'manage-platforms' => 'Can set/remove platform links of podcast #{id}.',
+        'manage-publications' => 'Can publish podcast #{id}.',
+        'manage-notifications' => 'Can view and mark notifications as read for podcast #{id}.',
+        'interact-as' => 'Can interact as the podcast #{id} to favourite, share or reply to posts.',
+        'episodes.view' => 'Can view dashboards and analytics of podcast #{id}\'s episodes.',
+        'episodes.create' => 'Can create episodes for podcast #{id}.',
+        'episodes.edit' => 'Can edit episodes of podcast #{id}.',
+        'episodes.delete' => 'Can delete episodes of podcast #{id}.',
+        'episodes.manage-persons' => 'Can manage episode persons of podcast #{id}.',
+        'episodes.manage-clips' => 'Can manage video clips or soundbites of podcast #{id}.',
+        'episodes.manage-publications' => 'Can publish/unpublish episodes and posts of podcast #{id}.',
+        'episodes.manage-comments' => 'Can create/remove episode comments of podcast #{id}.',
+    ],
+
+    // missing keys
+    'code' => 'Your 6-digit code',
+
+    'notEnoughPrivilege' => 'You do not have sufficient permissions to access that page.',
+    'set_password' => 'Set your password',
+
+    // Welcome email
+    'welcomeSubject' => 'You\'ve been invited to {siteName}',
+    'emailWelcomeMailBody' => 'An account was created for you on {domain}, click on the login link below to set your password. The link is valid for {numberOfHours} hours after this email was sent.',
+];
diff --git a/modules/Auth/Language/fr2/Contributor.php b/modules/Auth/Language/fr2/Contributor.php
new file mode 100644
index 0000000000000000000000000000000000000000..c70badc0a12e55a270b55c3450314d06e6c328c8
--- /dev/null
+++ b/modules/Auth/Language/fr2/Contributor.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'podcast_contributors' => 'Podcast contributors',
+    'view' => "{username}'s contribution to {podcastTitle}",
+    'add' => 'Add contributor',
+    'add_contributor' => 'Add a contributor for {0}',
+    'edit_role' => 'Update role for {0}',
+    'edit' => 'Edit',
+    'remove' => 'Remove',
+    'list' => [
+        'username' => 'Username',
+        'role' => 'Role',
+    ],
+    'form' => [
+        'user' => 'User',
+        'user_placeholder' => 'Select a user…',
+        'role' => 'Role',
+        'role_placeholder' => 'Select its role…',
+        'submit_add' => 'Add contributor',
+        'submit_edit' => 'Update role',
+    ],
+    'delete_form' => [
+        'title' => 'Remove {contributor}',
+        'disclaimer' =>
+            'You are about to remove {contributor} from contributors. They will not be able to access "{podcastTitle}" anymore.',
+        'understand' => 'I understand, I want to remove {contributor} from "{podcastTitle}"',
+        'submit' => 'Remove',
+    ],
+    'messages' => [
+        'editSuccess' => 'Role successfully changed!',
+        'editOwnerError' => "You can't edit the podcast owner!",
+        'removeOwnerError' => "You can't remove the podcast owner!",
+        'removeSuccess' =>
+            'You have successfully removed {username} from {podcastTitle}',
+        'alreadyAddedError' =>
+            "The contributor you're trying to add has already been added!",
+    ],
+];
diff --git a/modules/Auth/Language/fr2/MyAccount.php b/modules/Auth/Language/fr2/MyAccount.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ebbb30ef70a5e3e86a9bab867f7c732ce79db26
--- /dev/null
+++ b/modules/Auth/Language/fr2/MyAccount.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'info' => 'My account info',
+    'changePassword' => 'Change my password',
+    'messages' => [
+        'wrongPasswordError' => "You've entered the wrong password, try again.",
+        'passwordChangeSuccess' => 'Password has been successfully changed!',
+    ],
+];
diff --git a/modules/Auth/Language/fr2/User.php b/modules/Auth/Language/fr2/User.php
new file mode 100644
index 0000000000000000000000000000000000000000..32ec560cd59e47e5413f93f5e941d2708534db99
--- /dev/null
+++ b/modules/Auth/Language/fr2/User.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'edit_role' => "Edit {username}'s role",
+    'ban' => 'Ban',
+    'unban' => 'Unban',
+    'delete' => 'Delete',
+    'create' => 'New user',
+    'view' => "{username}'s info",
+    'all_users' => 'All users',
+    'list' => [
+        'user' => 'User',
+        'role' => 'Role',
+        'banned' => 'Banned?',
+    ],
+    'form' => [
+        'email' => 'Email',
+        'username' => 'Username',
+        'password' => 'Password',
+        'new_password' => 'New Password',
+        'role' => 'Role',
+        'roles' => 'Roles',
+        'permissions' => 'Permissions',
+        'submit_create' => 'Create user',
+        'submit_edit' => 'Save',
+        'submit_password_change' => 'Change!',
+    ],
+    'delete_form' => [
+        'title' => 'Delete {user}',
+        'disclaimer' =>
+            "You are about to delete {user} permanently. They will not be able to access the admin area anymore.",
+        'understand' => 'I understand, I want to delete {user} permanently',
+        'submit' => 'Delete',
+    ],
+    'messages' => [
+        'createSuccess' =>
+            'User created successfully! A welcome email was sent to {username} with a login link, they will be prompted with a password reset upon first authentication.',
+        'roleEditSuccess' =>
+            "{username}'s roles have been successfully updated.",
+        'banSuccess' => '{username} has been banned.',
+        'unbanSuccess' => '{username} has been unbanned.',
+        'editOwnerError' =>
+            '{username} is the instance owner, one does not simply touch the owner…',
+        'banSuperAdminError' =>
+            '{username} is a superadmin, one does not simply ban a superadmin…',
+        'deleteOwnerError' =>
+            '{username} is the instance owner, one does not simply delete the owner…',
+        'deleteSuperAdminError' =>
+            '{username} is a superadmin, one does not simply delete a superadmin…',
+        'deleteSuccess' => '{username} has been deleted.',
+    ],
+];
diff --git a/modules/Install/Language/fr2/Install.php b/modules/Install/Language/fr2/Install.php
new file mode 100644
index 0000000000000000000000000000000000000000..45d2608580b2c13f6c29ab1a664b6136c37acf64
--- /dev/null
+++ b/modules/Install/Language/fr2/Install.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'title' => 'Castopod installer',
+    'manual_config' => 'Manual configuration',
+    'manual_config_subtitle' =>
+        'Create a `.env` file with your settings and refresh the page to continue installation.',
+    'form' => [
+        'instance_config' => 'Instance configuration',
+        'hostname' => 'Hostname',
+        'media_base_url' => 'Media base URL',
+        'media_base_url_hint' =>
+            'If you use a CDN and/or an external analytics service, you may set them here.',
+        'admin_gateway' => 'Admin gateway',
+        'admin_gateway_hint' =>
+            'The route to access the admin area (eg. https://example.com/cp-admin). It is set by default as cp-admin, we recommend you change it for security reasons.',
+        'auth_gateway' => 'Auth gateway',
+        'auth_gateway_hint' =>
+            'The route to access the authentication pages (eg. https://example.com/cp-auth). It is set by default as cp-auth, we recommend you change it for security reasons.',
+        'database_config' => 'Database configuration',
+        'database_config_hint' =>
+            'Castopod needs to connect to your MySQL (or MariaDB) database. If you do not have these required info, please contact your server administrator.',
+        'db_hostname' => 'Database hostname',
+        'db_name' => 'Database name',
+        'db_username' => 'Database username',
+        'db_password' => 'Database password',
+        'db_prefix' => 'Database prefix',
+        'db_prefix_hint' =>
+            "The prefix of the Castopod table names, leave as is if you don't know what it means.",
+        'cache_config' => 'Cache configuration',
+        'cache_config_hint' =>
+            'Choose your preferred cache handler. Leave it as the default value if you have no clue what it means.',
+        'cache_handler' => 'Cache handler',
+        'cacheHandlerOptions' => [
+            'file' => 'File',
+            'redis' => 'Redis',
+            'predis' => 'Predis',
+        ],
+        'next' => 'Next',
+        'submit' => 'Finish install',
+        'create_superadmin' => 'Create your Super Admin account',
+        'email' => 'Email',
+        'username' => 'Username',
+        'password' => 'Password',
+    ],
+    'messages' => [
+        'createSuperAdminSuccess' =>
+            'Your superadmin account has been created successfully. Login to start podcasting!',
+        'databaseConnectError' =>
+            'Castopod could not connect to your database. Edit your database configuration and try again.',
+        'writeError' =>
+            "Couldn't create/write the `.env` file. You must create it manually by following the `.env.example` file template in the Castopod package.",
+    ],
+];
diff --git a/modules/PremiumPodcasts/Language/fr2/PremiumPodcasts.php b/modules/PremiumPodcasts/Language/fr2/PremiumPodcasts.php
new file mode 100644
index 0000000000000000000000000000000000000000..18c0dd4e4eb0738dad1f3106b9f35d3629918c4f
--- /dev/null
+++ b/modules/PremiumPodcasts/Language/fr2/PremiumPodcasts.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2022 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'podcast_is_premium' => 'Podcast contains premium episodes',
+    'episode_is_premium' => 'Episode is premium, only available to premium subscribers',
+    'unlock_episode' => 'This episode is for premium subscribers only. Click to unlock it!',
+    'banner_unlock' => 'This podcast contains premium episodes, only available to premium subscribers.',
+    'banner_lock' => 'Podcast is unlocked, enjoy the premium episodes!',
+    'subscribe' => 'Subscribe',
+    'lock' => 'Lock',
+    'unlock' => 'Unlock',
+    'unlock_form' => [
+        'title' => 'Premium content',
+        'subtitle' => 'This podcast contains locked premium episodes! Do you have the key to unlock them?',
+        'token' => 'Enter your key',
+        'token_hint' => 'If you are subscribed to {podcastTitle}, you may copy the key that was sent to you via email and paste it here.',
+        'submit' => 'Unlock all episodes!',
+        'call_to_action' => 'Unlock all episodes of {podcastTitle}:',
+        'subscribe_cta' => 'Subscribe now!',
+    ],
+    'messages' => [
+        'unlockSuccess' => 'Podcast was successfully unlocked! Enjoy the premium episodes!',
+        'unlockBadAttempt' => 'Your key does not seem to be working…',
+        'lockSuccess' => 'Podcast was successfully locked!',
+    ],
+];
diff --git a/modules/PremiumPodcasts/Language/fr2/Subscription.php b/modules/PremiumPodcasts/Language/fr2/Subscription.php
new file mode 100644
index 0000000000000000000000000000000000000000..f8af256f703a082b9a8f3577e1db6085dbb5596a
--- /dev/null
+++ b/modules/PremiumPodcasts/Language/fr2/Subscription.php
@@ -0,0 +1,100 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright  2022 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'podcast_subscriptions' => 'Podcast subscriptions',
+    'add' => 'New subscription',
+    'view' => 'View subscription',
+    'edit' => 'Edit subscription',
+    'regenerate_token' => 'Regenerate token',
+    'suspend' => 'Suspend subscription',
+    'resume' => 'Resume subscription',
+    'delete' => 'Delete subscription',
+    'status' => [
+        'active' => 'Active',
+        'suspended' => 'Suspended',
+        'expired' => 'Expired',
+    ],
+    'list' => [
+        'number' => 'Number',
+        'email' => 'Email',
+        'expiration_date' => 'Expiration date',
+        'unlimited' => 'Unlimited',
+        'downloads' => 'Downloads',
+        'status' => 'Status',
+    ],
+    'form' => [
+        'email' => 'Email',
+        'expiration_date' => 'Expiration date',
+        'expiration_date_hint' => 'The date and time at which the subscription expires. Leave empty for an unlimited subscription.',
+        'submit_add' => 'Add subscription',
+        'submit_edit' => 'Edit subscription',
+    ],
+    'form_link_add' => [
+        'link' => 'Subscription page link',
+        'link_hint' => 'This will add a call to action in the website inviting listeners to subscribe to the podcast.',
+        'submit' => 'Save link',
+    ],
+    'suspend_form' => [
+        'disclaimer' => 'Suspending the subscription will restrict the subscriber from having access to the premium content. You will still be able to lift the suspension afterwards.',
+        'reason' => 'Reason',
+        'reason_placeholder' => 'Why are you suspending the subscription?',
+        "submit" => 'Suspend subscription',
+    ],
+    'delete_form' => [
+        'disclaimer' => 'Deleting {subscriber}\'s subscription will remove all analytics data associated with it.',
+        'understand' => 'I understand, remove the subscription permanently',
+        'submit' => 'Remove subscription',
+    ],
+    'messages' => [
+        'addSuccess' => 'New subscription added! A welcome email was sent to {subscriber}.',
+        'addError' => 'Subscription could not be added.',
+        'editSuccess' => 'Subscription expiry date was updated! An email was sent to {subscriber}.',
+        'editError' => 'Subscription could not be edited.',
+        'regenerateTokenSuccess' => 'Token regenerated! An email was sent to {subscriber} with the new token.',
+        'regenerateTokenError' => 'Token could not be regenerated.',
+        'deleteSuccess' => 'Subscription was removed! An email was sent to {subscriber}.',
+        'deleteError' => 'Subscription could not be removed.',
+        'suspendSuccess' => 'Subscription was suspended! An email was sent to {subscriber}.',
+        'suspendError' => 'Subscription could not be suspended.',
+        'resumeSuccess' => 'Subscription was resumed! An email was sent to {subscriber}.',
+        'resumeError' => 'Subscription could not be resumed.',
+        'linkSaveSuccess' => 'Subscription link was saved successfully! It will appear in the website as a Call To Action!',
+        'linkRemoveSuccess' => 'Subscription link was removed successfully!',
+    ],
+    'emails' => [
+        'greeting' => 'Hey,',
+        'token' => 'Your token: {0}',
+        'unique_feed_link' => 'Your unique feed link: {0}',
+        'how_to_use' => 'How to use?',
+        'two_ways' => 'You have two ways of unlocking the premium episodes:',
+        'import_into_app' => 'Copy your unique feed url inside your favourite podcast app (import it as a private feed to prevent exposing your credentials).',
+        'go_to_website' => 'Go to {podcastWebsite}\'s website and unlock the podcast with your token.',
+        'welcome_subject' => 'Welcome to {podcastTitle}',
+        'welcome' => 'You have subscribed to {podcastTitle}, thank you and welcome aboard!',
+        'welcome_token_title' => 'Here are your credentials to unlock the podcast\'s premium episodes:',
+        'welcome_expires' => 'Your subscription was set to expire on {0}.',
+        'welcome_never_expires' => 'Your subscription was set to never expire.',
+        'reset_subject' => 'Your token was reset!',
+        'reset_token' => 'Your access to {podcastTitle} has been reset!',
+        'reset_token_title' => 'New credentials have been generated for you to unlock the podcast\'s premium episodes:',
+        'edited_subject' => 'Your subscription has been updated!',
+        'edited_expires' => 'Your subscription for {podcastTitle} was set to expire on {expiresAt}.',
+        'edited_never_expires' => 'Your subscription for {podcastTitle} was set to never expire!',
+        'suspended_subject' => 'Your subscription has been suspended!',
+        'suspended' => 'Your subscription for {podcastTitle} has been suspended! You can no longer access the podcast\'s premium episodes.',
+        'suspended_reason' => 'That is for the following reason: {0}',
+        'resumed_subject' => 'Your subscription has been resumed!',
+        'resumed' => 'Your subscription for {podcastTitle} has been resumed! You may access the podcast\'s premium episodes again.',
+        'deleted_subject' => 'Your subscription has been removed!',
+        'deleted' => 'Your subscription for {podcastTitle} has been removed! You no longer have access to the podcast\'s premium episodes.',
+        'footer' => '{castopod} hosted on {host}',
+    ],
+];