diff --git a/app/Language/ar/Episode.php b/app/Language/ar/Episode.php
index 926c9237..bbe4c785 100644
--- a/app/Language/ar/Episode.php
+++ b/app/Language/ar/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'التعليقات',
     'activity' => 'النشاط',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'وصف الحلقة',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comment}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/br/Episode.php b/app/Language/br/Episode.php
index 319aafbd..604aa11e 100644
--- a/app/Language/br/Episode.php
+++ b/app/Language/br/Episode.php
@@ -27,6 +27,7 @@ return [
     'comments' => 'Evezhiadennoù',
     'activity' => 'Oberiantiz',
     'chapters' => 'Chabistroù',
+    'transcript' => 'Transcript',
     'description' => 'Deskrivadur ar rann',
     'number_of_comments' => '{numberOfComments, plural,
         one {# evezhiadenn}
@@ -50,4 +51,6 @@ return [
         'publish_edit' => 'Kemmañ an embannadur',
     ],
     'no_chapters' => 'N\'eus chabistr ebet evit ar rann.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/ca/Episode.php b/app/Language/ca/Episode.php
index 24bd1869..88af06d2 100644
--- a/app/Language/ca/Episode.php
+++ b/app/Language/ca/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comentaris',
     'activity' => 'Activitat',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Descripció de l\'episodi',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comentari}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/da/Episode.php b/app/Language/da/Episode.php
index 71af978f..7e518721 100644
--- a/app/Language/da/Episode.php
+++ b/app/Language/da/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Kommentarer',
     'activity' => 'Aktivitet',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Episodebeskrivelse',
     'number_of_comments' => '{numberOfComments, plural,
         one {# kommentar}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/de/Episode.php b/app/Language/de/Episode.php
index de381a82..dba15335 100644
--- a/app/Language/de/Episode.php
+++ b/app/Language/de/Episode.php
@@ -23,7 +23,8 @@ return [
     'back_to_episodes' => 'Zurück zu Episoden von {podcast}',
     'comments' => 'Kommentare',
     'activity' => 'Aktivitäten',
-    'chapters' => 'Chapters',
+    'chapters' => 'Kapitel',
+    'transcript' => 'Transcript',
     'description' => 'Beschreibung der Episode',
     'number_of_comments' => '{numberOfComments, plural,
         one {# Kommentar}
@@ -43,5 +44,7 @@ return [
         'publish' => 'Veröffentlichen',
         'publish_edit' => 'Veröffentlichung bearbeiten',
     ],
-    'no_chapters' => 'No chapters are available for this episode.',
+    'no_chapters' => 'Für diese Episode sind keine Kapitel verfügbar.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/de/Podcast.php b/app/Language/de/Podcast.php
index 10f71485..63a83d60 100644
--- a/app/Language/de/Podcast.php
+++ b/app/Language/de/Podcast.php
@@ -51,5 +51,5 @@ return [
         other {# Personen}
     }',
     'persons_list' => 'Mitwirkende',
-    'castopod_website' => 'Castopod (website)',
+    'castopod_website' => 'Castopod (Webseite)',
 ];
diff --git a/app/Language/el/Episode.php b/app/Language/el/Episode.php
index 1c1f84ce..8cdaf3fc 100644
--- a/app/Language/el/Episode.php
+++ b/app/Language/el/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Σχόλια',
     'activity' => 'Δραστηριότητα',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Περιγραφή επεισοδίου',
     'number_of_comments' => '{numberOfComments, plural,
         one {# σχόλιο}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/es/Episode.php b/app/Language/es/Episode.php
index 7283d79e..df9fadc4 100644
--- a/app/Language/es/Episode.php
+++ b/app/Language/es/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comentarios',
     'activity' => 'Actividad',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Descripción del episodio',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comentario}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/eu/Comment.php b/app/Language/eu/Comment.php
new file mode 100644
index 00000000..1dd8f5ea
--- /dev/null
+++ b/app/Language/eu/Comment.php
@@ -0,0 +1,34 @@
+<?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' => "{actorDisplayName}'s comment for {episodeTitle}",
+    'back_to_comments' => 'Back to comments',
+    'form' => [
+        'episode_message_placeholder' => 'Write a comment…',
+        'reply_to_placeholder' => 'Reply to @{actorUsername}',
+        'submit' => 'Send',
+        'submit_reply' => 'Reply',
+    ],
+    'likes' => '{numberOfLikes, plural,
+        one {# like}
+        other {# likes}
+    }',
+    'replies' => '{numberOfReplies, plural,
+        one {# reply}
+        other {# replies}
+    }',
+    'like' => 'Like',
+    'reply' => 'Reply',
+    'view_replies' => 'View replies ({numberOfReplies})',
+    'block_actor' => 'Block user @{actorUsername}',
+    'block_domain' => 'Block domain @{actorDomain}',
+    'delete' => 'Delete comment',
+];
diff --git a/app/Language/eu/Common.php b/app/Language/eu/Common.php
new file mode 100644
index 00000000..1258afcc
--- /dev/null
+++ b/app/Language/eu/Common.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 [
+    'yes' => 'Yes',
+    'no' => 'No',
+    'cancel' => 'Cancel',
+    'optional' => 'Optional',
+    'close' => 'Close',
+    'home' => 'Home',
+    'explicit' => 'Explicit',
+    'powered_by' => 'Powered by {castopod}',
+    'go_back' => 'Go back',
+    'play_episode_button' => [
+        'play' => 'Play',
+        'playing' => 'Playing',
+    ],
+    'read_more' => 'Read more',
+    'read_less' => 'Read less',
+    'see_more' => 'See more',
+    'see_less' => 'See less',
+    'legal_notice' => 'Legal notice',
+];
diff --git a/app/Language/eu/Episode.php b/app/Language/eu/Episode.php
new file mode 100644
index 00000000..c2ed2b80
--- /dev/null
+++ b/app/Language/eu/Episode.php
@@ -0,0 +1,50 @@
+<?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 [
+    'season' => 'Season {seasonNumber}',
+    'season_abbr' => 'S{seasonNumber}',
+    'number' => 'Episode {episodeNumber}',
+    'number_abbr' => 'Ep. {episodeNumber}',
+    'season_episode' => 'Season {seasonNumber} episode {episodeNumber}',
+    'season_episode_abbr' => 'S{seasonNumber}:E{episodeNumber}',
+    'persons' => '{personsCount, plural,
+        one {# person}
+        other {# persons}
+    }',
+    'persons_list' => 'Persons',
+    'back_to_episodes' => 'Back to episodes of {podcast}',
+    'comments' => 'Comments',
+    'activity' => 'Activity',
+    'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
+    'description' => 'Episode description',
+    'number_of_comments' => '{numberOfComments, plural,
+        one {# comment}
+        other {# comments}
+    }',
+    'all_podcast_episodes' => 'All podcast episodes',
+    'back_to_podcast' => 'Go back to podcast',
+    'preview' => [
+        'title' => 'Preview',
+        'not_published' => 'Not published',
+        'text' => '{publication_status, select,
+            published {This episode is not yet published.}
+            scheduled {This episode is scheduled for publication on {publication_date}.}
+            with_podcast {This episode will be published at the same time as the podcast.}
+            other {This episode is not yet published.}
+        }',
+        'publish' => 'Publish',
+        'publish_edit' => 'Edit publication',
+    ],
+    'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
+];
diff --git a/app/Language/eu/Fediverse.php b/app/Language/eu/Fediverse.php
new file mode 100644
index 00000000..32f54c07
--- /dev/null
+++ b/app/Language/eu/Fediverse.php
@@ -0,0 +1,37 @@
+<?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 [
+    'your_handle' => 'Your handle',
+    'your_handle_hint' => 'Enter the @username@domain you want to act from.',
+    'follow' => [
+        'label' => 'Follow',
+        'title' => 'Follow {actorDisplayName}',
+        'subtitle' => 'You are going to follow:',
+        'accountNotFound' => 'The account could not be found.',
+        'remoteFollowNotAllowed' => 'Seems like the account server does not allow remote follows…',
+        'submit' => 'Proceed to follow',
+    ],
+    'favourite' => [
+        'title' => "Favourite {actorDisplayName}'s post",
+        'subtitle' => 'You are going to favourite:',
+        'submit' => 'Proceed to favourite',
+    ],
+    'reblog' => [
+        'title' => "Share {actorDisplayName}'s post",
+        'subtitle' => 'You are going to share:',
+        'submit' => 'Proceed to share',
+    ],
+    'reply' => [
+        'title' => "Reply to {actorDisplayName}'s post",
+        'subtitle' => 'You are going to reply to:',
+        'submit' => 'Proceed to reply',
+    ],
+];
diff --git a/app/Language/eu/Home.php b/app/Language/eu/Home.php
new file mode 100644
index 00000000..1518239b
--- /dev/null
+++ b/app/Language/eu/Home.php
@@ -0,0 +1,20 @@
+<?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',
+    'sort_by' => 'Sort by',
+    'sort_options' => [
+        'activity' => 'Recent activity',
+        'created_desc' => 'Newest first',
+        'created_asc' => 'Oldest first',
+    ],
+    'no_podcast' => 'No podcast found',
+];
diff --git a/app/Language/eu/Page.php b/app/Language/eu/Page.php
new file mode 100644
index 00000000..7cd60669
--- /dev/null
+++ b/app/Language/eu/Page.php
@@ -0,0 +1,17 @@
+<?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',
+    'map' => [
+        'title' => 'Map',
+        'description' => 'Discover podcast episodes on {siteName} that are placed on a map! Travel through the map and listen to episodes that talk about specific locations.',
+    ],
+];
diff --git a/app/Language/eu/Podcast.php b/app/Language/eu/Podcast.php
new file mode 100644
index 00000000..2798fcdd
--- /dev/null
+++ b/app/Language/eu/Podcast.php
@@ -0,0 +1,55 @@
+<?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 [
+    'feed' => 'RSS Podcast feed',
+    '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',
+    'followTitle' => 'Follow {actorDisplayName} on the fediverse!',
+    'followers' => '{numberOfFollowers, plural,
+        one {# follower}
+        other {# followers}
+    }',
+    'posts' => '{numberOfPosts, plural,
+        one {# post}
+        other {# posts}
+    }',
+    'links' => 'Links',
+    'activity' => 'Activity',
+    'episodes' => 'Episodes',
+    'episodes_title' => 'Episodes of {podcastTitle}',
+    'about' => 'About',
+    'stats' => [
+        'title' => 'Stats',
+        'number_of_seasons' => '{0, plural,
+            one {# season}
+            other {# seasons}
+        }',
+        'number_of_episodes' => '{0, plural,
+            one {# episode}
+            other {# episodes}
+        }',
+        'first_published_at' => 'First episode published on {0, date, medium}',
+    ],
+    'sponsor' => 'Sponsor',
+    'funding_links' => 'Funding links for {podcastTitle}',
+    'find_on' => 'Find {podcastTitle} on',
+    'listen_on' => 'Listen on',
+    'persons' => '{personsCount, plural,
+        one {# person}
+        other {# persons}
+    }',
+    'persons_list' => 'Persons',
+    'castopod_website' => 'Castopod (website)',
+];
diff --git a/app/Language/eu/Post.php b/app/Language/eu/Post.php
new file mode 100644
index 00000000..58d1cf80
--- /dev/null
+++ b/app/Language/eu/Post.php
@@ -0,0 +1,40 @@
+<?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' => "{actorDisplayName}'s post",
+    'back_to_actor_posts' => 'Back to {actor} posts',
+    'actor_shared' => '{actor} shared',
+    'reply_to' => 'Reply to @{actorUsername}',
+    'form' => [
+        'message_placeholder' => 'Write a message…',
+        'episode_message_placeholder' => 'Write a message for the episode…',
+        'episode_url_placeholder' => 'Episode URL',
+        'reply_to_placeholder' => 'Reply to @{actorUsername}',
+        'submit' => 'Send',
+        'submit_reply' => 'Reply',
+    ],
+    'favourites' => '{numberOfFavourites, plural,
+        one {# favourite}
+        other {# favourites}
+    }',
+    'reblogs' => '{numberOfReblogs, plural,
+        one {# share}
+        other {# shares}
+    }',
+    'replies' => '{numberOfReplies, plural,
+        one {# reply}
+        other {# replies}
+    }',
+    'expand' => 'Expand post',
+    'block_actor' => 'Block user @{actorUsername}',
+    'block_domain' => 'Block domain @{actorDomain}',
+    'delete' => 'Delete post',
+];
diff --git a/app/Language/fa/Episode.php b/app/Language/fa/Episode.php
index e3718380..f7ae1f56 100644
--- a/app/Language/fa/Episode.php
+++ b/app/Language/fa/Episode.php
@@ -23,6 +23,7 @@ return [
     'comments' => 'دیدگاه‌ها',
     'activity' => 'فعّالیت',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'شرح قسمت',
     'number_of_comments' => '{numberOfComments, plural,
         other {# نظر}
@@ -42,4 +43,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/fr/Episode.php b/app/Language/fr/Episode.php
index 46b30597..60afbea4 100644
--- a/app/Language/fr/Episode.php
+++ b/app/Language/fr/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Commentaires',
     'activity' => 'Activité',
     'chapters' => 'Chapitres',
+    'transcript' => 'Transcript',
     'description' => 'Description de l’épisode',
     'number_of_comments' => '{numberOfComments, plural,
         one {# commentaire}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Modifier la publication',
     ],
     'no_chapters' => 'Aucun chapitre n’est disponible pour cet épisode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/fr2/Episode.php b/app/Language/fr2/Episode.php
index e4e40600..3a386179 100644
--- a/app/Language/fr2/Episode.php
+++ b/app/Language/fr2/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Commentaires',
     'activity' => 'Activité',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Description de l’épisode',
     'number_of_comments' => '{numberOfComments, plural,
         one {# commentaire}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/fr_CA/Episode.php b/app/Language/fr_CA/Episode.php
index 7536120d..c2ed2b80 100644
--- a/app/Language/fr_CA/Episode.php
+++ b/app/Language/fr_CA/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comments',
     'activity' => 'Activity',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Episode description',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comment}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/gd/Episode.php b/app/Language/gd/Episode.php
index 0ac90de2..ab7a059b 100644
--- a/app/Language/gd/Episode.php
+++ b/app/Language/gd/Episode.php
@@ -26,6 +26,7 @@ return [
     'comments' => 'Beachdan',
     'activity' => 'Gnìomhachd',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Tuairisgeul an eapasoid',
     'number_of_comments' => '{numberOfComments, plural,
         one {# bheachd}
@@ -48,4 +49,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/gl/Episode.php b/app/Language/gl/Episode.php
index 43c16681..4ec2b27a 100644
--- a/app/Language/gl/Episode.php
+++ b/app/Language/gl/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comentarios',
     'activity' => 'Actividade',
     'chapters' => 'Capítulos',
+    'transcript' => 'Transcript',
     'description' => 'Descrición do episodio',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comentario}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Editar publicación',
     ],
     'no_chapters' => 'Non hai capítulos dispoñibles para este episodio.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/id/Episode.php b/app/Language/id/Episode.php
index da29ac94..6b945267 100644
--- a/app/Language/id/Episode.php
+++ b/app/Language/id/Episode.php
@@ -23,6 +23,7 @@ return [
     'comments' => 'Komentar',
     'activity' => 'Aktivitas',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Keterangan episode',
     'number_of_comments' => '{numberOfComments, plural,
         other {# komentar}
@@ -42,4 +43,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/it/Episode.php b/app/Language/it/Episode.php
index 6c1a8fe5..9ef6f615 100644
--- a/app/Language/it/Episode.php
+++ b/app/Language/it/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Commenti',
     'activity' => 'Attività',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Descrizione dell\'episodio',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comment}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Modifica pubblicazione',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/ja/Comment.php b/app/Language/ja/Comment.php
index 48080eeb..a59e462b 100644
--- a/app/Language/ja/Comment.php
+++ b/app/Language/ja/Comment.php
@@ -27,8 +27,8 @@ return [
     }',
     'like' => 'いいね',
     'reply' => '返信する',
-    'view_replies' => 'View replies ({numberOfReplies})',
-    'block_actor' => 'Block user @{actorUsername}',
-    'block_domain' => 'Block domain @{actorDomain}',
+    'view_replies' => '返信を見る ({numberOfReplies})',
+    'block_actor' => 'ユーザー @{actorUsername} をブロック',
+    'block_domain' => 'ドメイン @{actorDomain} をブロック',
     'delete' => 'コメントを削除する',
 ];
diff --git a/app/Language/ja/Common.php b/app/Language/ja/Common.php
index 9e862c12..43b0af51 100644
--- a/app/Language/ja/Common.php
+++ b/app/Language/ja/Common.php
@@ -13,10 +13,10 @@ return [
     'no' => 'いいえ',
     'cancel' => 'キャンセル',
     'optional' => 'Optional',
-    'close' => 'Close',
+    'close' => '閉じる',
     'home' => 'ホーム',
-    'explicit' => 'Explicit',
-    'powered_by' => 'Powered by {castopod}',
+    'explicit' => '過激な内容を含む',
+    'powered_by' => '提供: {castopod}',
     'go_back' => '戻る',
     'play_episode_button' => [
         'play' => '再生',
@@ -24,7 +24,7 @@ return [
     ],
     'read_more' => '続きを読む',
     'read_less' => '閉じる',
-    'see_more' => 'See more',
-    'see_less' => 'See less',
-    'legal_notice' => 'Legal notice',
+    'see_more' => 'もっと見る',
+    'see_less' => '表示を減らす',
+    'legal_notice' => '法的事項',
 ];
diff --git a/app/Language/ja/Episode.php b/app/Language/ja/Episode.php
index 9af4cb7b..40b21d39 100644
--- a/app/Language/ja/Episode.php
+++ b/app/Language/ja/Episode.php
@@ -10,38 +10,40 @@ declare(strict_types=1);
 
 return [
     'season' => 'シーズン {seasonNumber}',
-    'season_abbr' => 'S{seasonNumber}',
+    'season_abbr' => 'シーズン {seasonNumber}',
     'number' => 'エピソード {episodeNumber}',
-    'number_abbr' => 'Ep. {episodeNumber}',
+    'number_abbr' => 'エピソード {episodeNumber}',
     'season_episode' => 'シーズン {seasonNumber} エピソード {episodeNumber}',
-    'season_episode_abbr' => 'S{seasonNumber}:E{episodeNumber}',
+    'season_episode_abbr' => 'シーズン{seasonNumber}エピソード{episodeNumber}',
     'persons' => '{personsCount, plural,
-        one {# person}
-        other {# persons}
+        other {# 人}
     }',
-    'persons_list' => 'Persons',
+    'persons_list' => '人物',
     'back_to_episodes' => '{podcast} のエピソードに戻る',
     'comments' => 'コメント',
     'activity' => 'アクティビティ',
-    'chapters' => 'Chapters',
-    'description' => 'Episode description',
+    'chapters' => '章',
+    'transcript' => 'Transcript',
+    'description' => 'エピソードの詳細',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comment}
         other {# comments}
     }',
-    'all_podcast_episodes' => 'All podcast episodes',
+    'all_podcast_episodes' => 'すべての Podcast エピソード',
     'back_to_podcast' => 'ポッドキャストへ戻る',
     'preview' => [
         'title' => 'プレビュー',
-        'not_published' => 'Not published',
+        'not_published' => '未公開',
         'text' => '{publication_status, select,
-            published {This episode is not yet published.}
-            scheduled {This episode is scheduled for publication on {publication_date}.}
-            with_podcast {This episode will be published at the same time as the podcast.}
-            other {This episode is not yet published.}
+            published {このエピソードはまだ公開されていません}
+            scheduled {このエピソードは {publication_date} に公開される予定です}
+            with_podcast {このエピソードはPodCastと同時に公開されます}
+            other {このエピソードはまだ公開されていません。}
         }',
         'publish' => '公開する',
-        'publish_edit' => 'Edit publication',
+        'publish_edit' => '出版物を編集',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/ja/Fediverse.php b/app/Language/ja/Fediverse.php
index c94e62f3..c86f8313 100644
--- a/app/Language/ja/Fediverse.php
+++ b/app/Language/ja/Fediverse.php
@@ -9,29 +9,29 @@ declare(strict_types=1);
  */
 
 return [
-    'your_handle' => 'Your handle',
+    'your_handle' => 'あなたのユーザー ID',
     'your_handle_hint' => 'Enter the @username@domain you want to act from.',
     'follow' => [
         'label' => 'フォロー',
         'title' => '{actorDisplayName} をフォロー',
         'subtitle' => 'You are going to follow:',
         'accountNotFound' => 'アカウントが見つかりませんでした',
-        'remoteFollowNotAllowed' => 'Seems like the account server does not allow remote follows…',
-        'submit' => 'Proceed to follow',
+        'remoteFollowNotAllowed' => 'このアカウントサーバーはリモートフォローを許可しておりません',
+        'submit' => 'フォローする',
     ],
     'favourite' => [
-        'title' => "Favourite {actorDisplayName}'s post",
+        'title' => "お気に入りの {actorDisplayName}の投稿",
         'subtitle' => 'You are going to favourite:',
-        'submit' => 'Proceed to favourite',
+        'submit' => 'お気に入り登録する',
     ],
     'reblog' => [
         'title' => "Share {actorDisplayName}'s post",
         'subtitle' => 'You are going to share:',
-        'submit' => 'Proceed to share',
+        'submit' => '共有する',
     ],
     'reply' => [
         'title' => "Reply to {actorDisplayName}'s post",
         'subtitle' => 'You are going to reply to:',
-        'submit' => 'Proceed to reply',
+        'submit' => '返信する',
     ],
 ];
diff --git a/app/Language/ja/Page.php b/app/Language/ja/Page.php
index 7cd60669..b961b40b 100644
--- a/app/Language/ja/Page.php
+++ b/app/Language/ja/Page.php
@@ -9,9 +9,9 @@ declare(strict_types=1);
  */
 
 return [
-    'back_to_home' => 'Back to home',
+    'back_to_home' => 'ホームへ戻る',
     'map' => [
-        'title' => 'Map',
-        'description' => 'Discover podcast episodes on {siteName} that are placed on a map! Travel through the map and listen to episodes that talk about specific locations.',
+        'title' => 'マップ',
+        'description' => '{siteName} でpodcastのエピソードを見つけましょう!マップを旅して、特定の場所について話すエピソードを聞きましょう。',
     ],
 ];
diff --git a/app/Language/ja/Podcast.php b/app/Language/ja/Podcast.php
index 2798fcdd..43d67e5d 100644
--- a/app/Language/ja/Podcast.php
+++ b/app/Language/ja/Podcast.php
@@ -9,29 +9,27 @@ declare(strict_types=1);
  */
 
 return [
-    'feed' => 'RSS Podcast feed',
-    'season' => 'Season {seasonNumber}',
-    'list_of_episodes_year' => '{year} episodes ({episodeCount})',
+    'feed' => 'RSS PodCastフィード',
+    'season' => 'シーズン {seasonNumber}',
+    'list_of_episodes_year' => '{year} エピソード ({episodeCount})',
     'list_of_episodes_season' =>
-        'Season {seasonNumber} episodes ({episodeCount})',
-    'no_episode' => 'No episode found!',
-    'follow' => 'Follow',
-    'followTitle' => 'Follow {actorDisplayName} on the fediverse!',
+        'シーズン {seasonNumber} エピソード({episodeCount})',
+    'no_episode' => 'エピソードが見つかりませんでした',
+    'follow' => 'フォロー',
+    'followTitle' => 'Fediverseで {actorDisplayName} をフォロー!',
     'followers' => '{numberOfFollowers, plural,
-        one {# follower}
-        other {# followers}
+        other {# 人のフォロワー}
     }',
     'posts' => '{numberOfPosts, plural,
-        one {# post}
-        other {# posts}
+        other {#件の投稿}
     }',
-    'links' => 'Links',
-    'activity' => 'Activity',
-    'episodes' => 'Episodes',
-    'episodes_title' => 'Episodes of {podcastTitle}',
-    'about' => 'About',
+    'links' => 'リンク',
+    'activity' => 'アクティビティー',
+    'episodes' => 'エピソード',
+    'episodes_title' => '{podcastTitle} のエピソード',
+    'about' => '概要',
     'stats' => [
-        'title' => 'Stats',
+        'title' => '統計',
         'number_of_seasons' => '{0, plural,
             one {# season}
             other {# seasons}
diff --git a/app/Language/kk/Episode.php b/app/Language/kk/Episode.php
index 7536120d..c2ed2b80 100644
--- a/app/Language/kk/Episode.php
+++ b/app/Language/kk/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comments',
     'activity' => 'Activity',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Episode description',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comment}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/ko/Episode.php b/app/Language/ko/Episode.php
index 7536120d..c2ed2b80 100644
--- a/app/Language/ko/Episode.php
+++ b/app/Language/ko/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comments',
     'activity' => 'Activity',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Episode description',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comment}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/nl/Episode.php b/app/Language/nl/Episode.php
index 81069be9..4acd9a29 100644
--- a/app/Language/nl/Episode.php
+++ b/app/Language/nl/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Reacties',
     'activity' => 'Activiteiten',
     'chapters' => 'Hoofdstukken',
+    'transcript' => 'Transcript',
     'description' => 'Omschrijving aflevering',
     'number_of_comments' => '{numberOfComments, plural,
         one {# reactie}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Publicatie bewerken',
     ],
     'no_chapters' => 'Voor deze aflevering zijn geen hoofdstukken beschikbaar.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/nn-NO/Episode.php b/app/Language/nn-NO/Episode.php
index 75ce64f3..c2bd60a3 100644
--- a/app/Language/nn-NO/Episode.php
+++ b/app/Language/nn-NO/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Kommentarar',
     'activity' => 'Aktivitet',
     'chapters' => 'Kapittel',
+    'transcript' => 'Transcript',
     'description' => 'Skildring av episoden',
     'number_of_comments' => '{numberOfComments, plural,
         one {# kommentar}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Rediger publiseringa',
     ],
     'no_chapters' => 'Det finst ingen kapittel for denne episoden.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/oc/Episode.php b/app/Language/oc/Episode.php
index 544dc054..de49b6f3 100644
--- a/app/Language/oc/Episode.php
+++ b/app/Language/oc/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comentaris',
     'activity' => 'Activitat',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Descripcion de l’episòdi',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comentari}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Modificar la publicacion',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/pl/Episode.php b/app/Language/pl/Episode.php
index dbbc3a15..3c744879 100644
--- a/app/Language/pl/Episode.php
+++ b/app/Language/pl/Episode.php
@@ -25,6 +25,7 @@ return [
     'comments' => 'Komentarze',
     'activity' => 'Aktywność',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Opis odcinka',
     'number_of_comments' => '{numberOfComments, plural,
         one {# komentarz}
@@ -46,4 +47,6 @@ return [
         'publish_edit' => 'Edytuj publikację',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/pt-BR/Episode.php b/app/Language/pt-BR/Episode.php
index f67265dc..dddddbe9 100644
--- a/app/Language/pt-BR/Episode.php
+++ b/app/Language/pt-BR/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comentários',
     'activity' => 'Atividade',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Descrição do episódio',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comentário}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Editar Publicação',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/pt/Episode.php b/app/Language/pt/Episode.php
index 7536120d..c2ed2b80 100644
--- a/app/Language/pt/Episode.php
+++ b/app/Language/pt/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Comments',
     'activity' => 'Activity',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Episode description',
     'number_of_comments' => '{numberOfComments, plural,
         one {# comment}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/ro/Episode.php b/app/Language/ro/Episode.php
index 9067ecad..cbfb226d 100644
--- a/app/Language/ro/Episode.php
+++ b/app/Language/ro/Episode.php
@@ -25,6 +25,7 @@ return [
     'comments' => 'Comentarii',
     'activity' => 'Activitate',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Descrierea episodului',
     'number_of_comments' => '{numberOfComments, plural,
         one {# răspuns}
@@ -46,4 +47,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/ru/Episode.php b/app/Language/ru/Episode.php
index fae4d2b6..0bd8850b 100644
--- a/app/Language/ru/Episode.php
+++ b/app/Language/ru/Episode.php
@@ -26,6 +26,7 @@ return [
     'comments' => 'Комментарии',
     'activity' => 'Активность',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Описание серии',
     'number_of_comments' => '{numberOfComments, plural,
         one {# комментарий}
@@ -48,4 +49,6 @@ return [
         'publish_edit' => 'Редактировать публикацию',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/sk/Episode.php b/app/Language/sk/Episode.php
index 3fd4b03b..e72bf8c0 100644
--- a/app/Language/sk/Episode.php
+++ b/app/Language/sk/Episode.php
@@ -26,6 +26,7 @@ return [
     'comments' => 'Komentáre',
     'activity' => 'Aktivita',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Popis epizódy',
     'number_of_comments' => '{numberOfComments, plural,
         one {# komentár}
@@ -48,4 +49,6 @@ return [
         'publish_edit' => 'Upraviť zverejnené',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/sr-Latn/Episode.php b/app/Language/sr-Latn/Episode.php
index 77a21c9c..b780a66c 100644
--- a/app/Language/sr-Latn/Episode.php
+++ b/app/Language/sr-Latn/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Komentari',
     'activity' => 'Aktivnosti',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Opis epizode',
     'number_of_comments' => '{numberOfComments, plural,
         one {# komentar}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Uredi objavu',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/sv/Episode.php b/app/Language/sv/Episode.php
index 12f94e21..b9ecb34a 100644
--- a/app/Language/sv/Episode.php
+++ b/app/Language/sv/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => 'Kommentarer',
     'activity' => 'Aktivitet',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Beskrivning av avsnitt',
     'number_of_comments' => '{numberOfComments, plural,
         one {# kommentar}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/uk/Episode.php b/app/Language/uk/Episode.php
index 15dc1f49..34343563 100644
--- a/app/Language/uk/Episode.php
+++ b/app/Language/uk/Episode.php
@@ -26,6 +26,7 @@ return [
     'comments' => 'Коментарі',
     'activity' => 'Активність',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => 'Опис Серії',
     'number_of_comments' => '{numberOfComments, plural,
         one {# коментар}
@@ -48,4 +49,6 @@ return [
         'publish_edit' => 'Редагувати публікацію',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/zh-Hans/Episode.php b/app/Language/zh-Hans/Episode.php
index e57ed248..316b90b7 100644
--- a/app/Language/zh-Hans/Episode.php
+++ b/app/Language/zh-Hans/Episode.php
@@ -24,6 +24,7 @@ return [
     'comments' => '评论',
     'activity' => '活动',
     'chapters' => 'Chapters',
+    'transcript' => 'Transcript',
     'description' => '剧集描述',
     'number_of_comments' => '{numberOfComments, plural,
         other {# 评论}
@@ -44,4 +45,6 @@ return [
         'publish_edit' => 'Edit publication',
     ],
     'no_chapters' => 'No chapters are available for this episode.',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
 ];
diff --git a/app/Language/zh-Hant/Comment.php b/app/Language/zh-Hant/Comment.php
new file mode 100644
index 00000000..c12c8419
--- /dev/null
+++ b/app/Language/zh-Hant/Comment.php
@@ -0,0 +1,32 @@
+<?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' => "{actorDisplayName}' 對於 {episodeTitle} 之評論",
+    'back_to_comments' => '返回到評論',
+    'form' => [
+        'episode_message_placeholder' => '發表留言...',
+        'reply_to_placeholder' => '回覆 @{actorUsername}',
+        'submit' => '送出',
+        'submit_reply' => '回覆',
+    ],
+    'likes' => '{numberOfLikes, plural,
+        other {# 讚}
+    }',
+    'replies' => '{numberOfReplies, plural,
+        other {# 回覆}
+    }',
+    'like' => '讚',
+    'reply' => '回覆',
+    'view_replies' => '檢視回覆 ({numberOfReplies})',
+    'block_actor' => '封鎖使用者 @{actorUsername}',
+    'block_domain' => '封鎖網域 @{actorDomain}',
+    'delete' => '刪除評論',
+];
diff --git a/app/Language/zh-Hant/Common.php b/app/Language/zh-Hant/Common.php
new file mode 100644
index 00000000..24b56e1a
--- /dev/null
+++ b/app/Language/zh-Hant/Common.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 [
+    'yes' => '是',
+    'no' => '否',
+    'cancel' => '取消',
+    'optional' => '選用項',
+    'close' => '關閉',
+    'home' => '首頁',
+    'explicit' => '露骨內容',
+    'powered_by' => '由 {castopod} 提供支援',
+    'go_back' => '返回',
+    'play_episode_button' => [
+        'play' => '播放',
+        'playing' => '播放中',
+    ],
+    'read_more' => '閱讀更多',
+    'read_less' => '顯示更少',
+    'see_more' => '顯示更多',
+    'see_less' => '顯示較少',
+    'legal_notice' => '法律聲明',
+];
diff --git a/app/Language/zh-Hant/Episode.php b/app/Language/zh-Hant/Episode.php
new file mode 100644
index 00000000..659207d1
--- /dev/null
+++ b/app/Language/zh-Hant/Episode.php
@@ -0,0 +1,50 @@
+<?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 [
+    'season' => '第{seasonNumber} 季',
+    'season_abbr' => 'S{seasonNumber}',
+    'number' => '第 {episodeNumber} 集',
+    'number_abbr' => 'Ep. {episodeNumber}',
+    'season_episode' => '第{seasonNumber} 季第{episodeNumber} 集',
+    'season_episode_abbr' => 'S{seasonNumber}:E{episodeNumber}',
+    'persons' => '{personsCount, plural,
+        one {# person}
+        other {# persons}
+    }',
+    'persons_list' => '人物',
+    'back_to_episodes' => '回到劇集 {podcast} 中',
+    'comments' => '註釋',
+    'activity' => '活動',
+    'chapters' => '章',
+    'transcript' => 'Transcript',
+    'description' => '節目介紹',
+    'number_of_comments' => '{numberOfComments, plural,
+        one {# 評論}
+        other {# 評論}
+    }',
+    'all_podcast_episodes' => '所有播客劇集',
+    'back_to_podcast' => '返回至播客',
+    'preview' => [
+        'title' => '預覽',
+        'not_published' => '未發佈',
+        'text' => '{publication_status, select,
+            published {本集尚未發佈。}
+            scheduled {本集排程於 {publication_date} 發佈}
+            with_podcast {本集將會與此播客同時發佈。}
+            other {本集尚未發佈。}
+        }',
+        'publish' => '發佈',
+        'publish_edit' => '編輯公開程度',
+    ],
+    'no_chapters' => '本劇集未有章節',
+    'download_transcript' => 'Download transcript ({extension})',
+    'no_transcript' => 'No transcript available for this episode.',
+];
diff --git a/app/Language/zh-Hant/Fediverse.php b/app/Language/zh-Hant/Fediverse.php
new file mode 100644
index 00000000..21ffff8e
--- /dev/null
+++ b/app/Language/zh-Hant/Fediverse.php
@@ -0,0 +1,37 @@
+<?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 [
+    'your_handle' => '你的帳號',
+    'your_handle_hint' => '輸入 @username@domain 您想要執行的操作。',
+    'follow' => [
+        'label' => '追蹤',
+        'title' => '追蹤 {actorDisplayName}',
+        'subtitle' => '您將會追蹤:',
+        'accountNotFound' => '找不到此帳號。',
+        'remoteFollowNotAllowed' => '似乎此帳號伺服器不允许遠端追蹤…',
+        'submit' => '繼續追蹤',
+    ],
+    'favourite' => [
+        'title' => "喜歡 {actorDisplayName} 的貼文",
+        'subtitle' => '您將會喜歡:',
+        'submit' => '加入最愛',
+    ],
+    'reblog' => [
+        'title' => "分享 {actorDisplayName} 的貼文",
+        'subtitle' => '您將要分享:',
+        'submit' => '繼續分享',
+    ],
+    'reply' => [
+        'title' => "回覆 {actorDisplayName} 的貼文",
+        'subtitle' => '您將要回覆:',
+        'submit' => '繼續回覆',
+    ],
+];
diff --git a/app/Language/zh-Hant/Home.php b/app/Language/zh-Hant/Home.php
new file mode 100644
index 00000000..05e464d8
--- /dev/null
+++ b/app/Language/zh-Hant/Home.php
@@ -0,0 +1,20 @@
+<?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' => '全部的播客',
+    'sort_by' => '排序方式',
+    'sort_options' => [
+        'activity' => '最近活動',
+        'created_desc' => '最新的優先',
+        'created_asc' => '最舊的優先',
+    ],
+    'no_podcast' => '没有找到播客',
+];
diff --git a/app/Language/zh-Hant/Page.php b/app/Language/zh-Hant/Page.php
new file mode 100644
index 00000000..9d683dcf
--- /dev/null
+++ b/app/Language/zh-Hant/Page.php
@@ -0,0 +1,17 @@
+<?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' => '回到首頁',
+    'map' => [
+        'title' => '地圖',
+        'description' => '在地圖上探索 {siteName} 的播客節目!優遊穿梭於地圖並收聽各地的節目。',
+    ],
+];
diff --git a/app/Language/zh-Hant/Podcast.php b/app/Language/zh-Hant/Podcast.php
new file mode 100644
index 00000000..86f2914a
--- /dev/null
+++ b/app/Language/zh-Hant/Podcast.php
@@ -0,0 +1,55 @@
+<?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 [
+    'feed' => '播客 RSS 摘要',
+    'season' => '第 {seasonNumber} 季',
+    'list_of_episodes_year' => '{year} 集數 ({episodeCount})',
+    'list_of_episodes_season' =>
+        '第 {seasonNumber} 季(第 {episodeCount} 集)',
+    'no_episode' => '没有找到節目!',
+    'follow' => '追蹤',
+    'followTitle' => '在聯邦宇宙中追蹤 {actorDisplayName} !',
+    'followers' => '{numberOfFollowers, plural,
+        one {# 追蹤者}
+        other {# 追蹤者}
+    }',
+    'posts' => '{numberOfPosts, plural,
+        one {# 貼文}
+        other {# 貼文}
+    }}',
+    'links' => '連結',
+    'activity' => '活動',
+    'episodes' => '劇集',
+    'episodes_title' => '{podcastTitle} 的劇集',
+    'about' => '關於',
+    'stats' => [
+        'title' => '統計',
+        'number_of_seasons' => '{0, plural,
+            one {# 季}
+            other {# 季}
+        }',
+        'number_of_episodes' => '{0, plural,
+            one {# 劇集}
+            other {# 劇集}
+        }',
+        'first_published_at' => '首集發佈於 {0, date, medium}',
+    ],
+    'sponsor' => '贊助者',
+    'funding_links' => '{podcastTitle} 的贊助連結',
+    'find_on' => '查找 {podcastTitle} 於',
+    'listen_on' => '收聽',
+    'persons' => '{personsCount, plural,
+        one {# 人}
+        other {# 人}
+    }',
+    'persons_list' => '人物',
+    'castopod_website' => 'Castopod (網站)',
+];
diff --git a/app/Language/zh-Hant/Post.php b/app/Language/zh-Hant/Post.php
new file mode 100644
index 00000000..76f88627
--- /dev/null
+++ b/app/Language/zh-Hant/Post.php
@@ -0,0 +1,40 @@
+<?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' => "{actorDisplayName} 的貼文",
+    'back_to_actor_posts' => '回到 {actor} 的貼文',
+    'actor_shared' => '{actor} 已分享',
+    'reply_to' => '回覆 @{actorUsername}',
+    'form' => [
+        'message_placeholder' => '輸入訊息…',
+        'episode_message_placeholder' => '替劇集寫一則訊息…',
+        'episode_url_placeholder' => '劇集網址',
+        'reply_to_placeholder' => '回覆給 @{actorUsername}',
+        'submit' => '送出',
+        'submit_reply' => '回覆',
+    ],
+    'favourites' => '{numberOfFavourites, plural,
+        one {# 喜歡}
+        other {# 喜歡}
+    }',
+    'reblogs' => '{numberOfReblogs, plural,
+        one {# 分享}
+        other {# 分享}
+    }',
+    'replies' => '{numberOfReplies, plural,
+        one {# 回覆}
+        other {# 回覆}
+    }',
+    'expand' => '展開貼文',
+    'block_actor' => '封鎖使用者 @{actorUsername}',
+    'block_domain' => '封鎖網域 @{actorDomain}',
+    'delete' => '刪除貼文',
+];
diff --git a/docs/src/ar/getting-started/docker.md b/docs/src/ar/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/ar/getting-started/docker.md
+++ b/docs/src/ar/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/br/getting-started/docker.md b/docs/src/br/getting-started/docker.md
index b6842152..ec96d3dc 100644
--- a/docs/src/br/getting-started/docker.md
+++ b/docs/src/br/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/ca/getting-started/docker.md b/docs/src/ca/getting-started/docker.md
index d8a6e91b..fe231b96 100644
--- a/docs/src/ca/getting-started/docker.md
+++ b/docs/src/ca/getting-started/docker.md
@@ -10,8 +10,8 @@ process:
 
 - [**`castopod/castopod`**](https://hub.docker.com/r/castopod/castopod): an all
   in one castopod image using nginx unit
-- [**`castopod/app`**](https://hub.docker.com/r/castopod/app): el paquet
-  incloent Castopod i totes les dependències
+- [** code>castopod/app</code>**](https://hub.docker.com/r/castopod/app): el
+  paquet incloent Castopod i totes les dependències
 - [**`castopod/web-server`**](https://hub.docker.com/r/castopod/web-server): una
   configuració de Nginx per a Castopod
 
@@ -48,6 +48,7 @@ una base de dades Redis com a gestor de memòria cau.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ una base de dades Redis com a gestor de memòria cau.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/da/getting-started/docker.md b/docs/src/da/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/da/getting-started/docker.md
+++ b/docs/src/da/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/de/getting-started/docker.md b/docs/src/de/getting-started/docker.md
index 814d0177..20713090 100644
--- a/docs/src/de/getting-started/docker.md
+++ b/docs/src/de/getting-started/docker.md
@@ -48,6 +48,7 @@ kann als Cache-Handler hinzugefügt werden.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ kann als Cache-Handler hinzugefügt werden.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/el/getting-started/docker.md b/docs/src/el/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/el/getting-started/docker.md
+++ b/docs/src/el/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/es/getting-started/docker.md b/docs/src/es/getting-started/docker.md
index 84331cab..63c2cf95 100644
--- a/docs/src/es/getting-started/docker.md
+++ b/docs/src/es/getting-started/docker.md
@@ -48,6 +48,7 @@ También se puede añadir una base de datos Redis como gestor de caché.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ También se puede añadir una base de datos Redis como gestor de caché.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/eu/getting-started/auth.md b/docs/src/eu/getting-started/auth.md
new file mode 100644
index 00000000..ff5d59c0
--- /dev/null
+++ b/docs/src/eu/getting-started/auth.md
@@ -0,0 +1,87 @@
+---
+title: Authentication & Authorization
+sidebarDepth: 3
+---
+
+# Authentication & Authorization
+
+Castopod handles authentication and authorization using `codeigniter/shield`
+coupled with custom rules. Roles and permissions are defined at two levels:
+
+1. [instance wide](#1-instance-wide-roles-and-permissions)
+2. [per podcast](#2-per-podcast-roles-and-permissions)
+
+## 1. Instance wide roles and permissions
+
+### Instance roles
+
+<!-- AUTH-INSTANCE-ROLES-LIST:START - Do not remove or modify this section -->
+
+| role        | description                         | permissions                                                                                |
+| ----------- | ----------------------------------- | ------------------------------------------------------------------------------------------ |
+| Super admin | Has complete control over Castopod. | admin.\*, podcasts.\*, users.manage, persons.manage, pages.manage, fediverse.manage-blocks |
+| Manager     | Manages Castopod's content.         | podcasts.create, podcasts.import, persons.manage, pages.manage                             |
+| Podcaster   | General users of Castopod.          | admin.access                                                                               |
+
+<!-- AUTH-INSTANCE-ROLES-LIST:END -->
+
+### Instance permissions
+
+<!-- AUTH-INSTANCE-PERMISSIONS-LIST:START - Do not remove or modify this section -->
+
+| permission              | description                                                        |
+| ----------------------- | ------------------------------------------------------------------ |
+| 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. |
+
+<!-- AUTH-INSTANCE-PERMISSIONS-LIST:END -->
+
+## 2. Per podcast roles and permissions
+
+### Per podcast roles
+
+<!-- AUTH-PODCAST-ROLES-LIST:START - Do not remove or modify this section -->
+
+| role   | description                                               | permissions                                                                                                                                                                                                                                                                                 |
+| ------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Admin  | Has complete control of podcast #{id}.                    | \*                                                                                                                                                                                                                                                                                          |
+| Editor | Manages content and publications of podcast #{id}.        | view, edit, manage-import, manage-persons, manage-platforms, manage-publications, manage-notifications, interact-as, episodes.view, episodes.create, episodes.edit, episodes.delete, episodes.manage-persons, episodes.manage-clips, episodes.manage-publications, episodes.manage-comments |
+| Author | Manages content of podcast #{id} but cannot publish them. | view, manage-persons, episodes.view, episodes.create, episodes.edit, episodes.manage-persons, episodes.manage-clips                                                                                                                                                                         |
+| Guest  | General contributor of the podcast #{id}.                 | view, episodes.view                                                                                                                                                                                                                                                                         |
+
+<!-- AUTH-PODCAST-ROLES-LIST:END -->
+
+### Per podcast permissions
+
+<!-- AUTH-PODCAST-PERMISSIONS-LIST:START - Do not remove or modify this section -->
+
+| permission                   | description                                                              |
+| ---------------------------- | ------------------------------------------------------------------------ |
+| 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 dashboard and analytics of podcast #{id}.                       |
+| episodes.create              | Can create episodes for podcast #{id}.                                   |
+| episodes.edit                | Can edit podcast #{id}.                                                  |
+| episodes.delete              | Can delete podcast #{id}.                                                |
+| episodes.manage-persons      | Can manage subscriptions of podcast #{id}.                               |
+| episodes.manage-clips        | Can manage video clips or soundbites of podcast #{id}.                   |
+| episodes.manage-publications | Can publish podcast #{id}.                                               |
+| episodes.manage-comments     | Can create/remove episode comments of podcast #{id}.                     |
+
+<!-- AUTH-PODCAST-PERMISSIONS-LIST:END -->
diff --git a/docs/src/eu/getting-started/docker.md b/docs/src/eu/getting-started/docker.md
new file mode 100644
index 00000000..12f01619
--- /dev/null
+++ b/docs/src/eu/getting-started/docker.md
@@ -0,0 +1,160 @@
+---
+title: Official Docker images
+sidebarDepth: 3
+---
+
+# Official Docker images
+
+Castopod pushes 3 Docker images to the Docker Hub during its automated build
+process:
+
+- [**`castopod/castopod`**](https://hub.docker.com/r/castopod/castopod): an all
+  in one castopod image using nginx unit
+- [**`castopod/app`**](https://hub.docker.com/r/castopod/app): the app bundle
+  with all of Castopod dependencies
+- [**`castopod/web-server`**](https://hub.docker.com/r/castopod/web-server): an
+  Nginx configuration for Castopod
+
+Additionally, Castopod requires a MySQL-compatible database. A Redis database
+can be added as a cache handler.
+
+## Supported tags
+
+- `develop` [unstable], latest development branch build
+- `beta` [stable], latest beta version build
+- `latest` [stable], latest version build
+- `1.x.x` [stable], specific version build (since `1.0.0`)
+
+## Example usage
+
+1.  Install [docker](https://docs.docker.com/get-docker/) and
+    [docker-compose](https://docs.docker.com/compose/install/)
+2.  Create a `docker-compose.yml` file with the following:
+
+    ```yml
+    version: "3.7"
+
+    services:
+      app:
+        image: castopod/castopod:latest
+        container_name: "castopod-app"
+        volumes:
+          - castopod-media:/var/www/castopod/public/media
+        environment:
+          MYSQL_DATABASE: castopod
+          MYSQL_USER: castopod
+          MYSQL_PASSWORD: changeme
+          CP_BASEURL: "https://castopod.example.com"
+          CP_ANALYTICS_SALT: changeme
+          CP_CACHE_HANDLER: redis
+          CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
+        networks:
+          - castopod-app
+          - castopod-db
+        ports:
+          - 8000:8000
+        restart: unless-stopped
+
+      mariadb:
+        image: mariadb:10.5
+        container_name: "castopod-mariadb"
+        networks:
+          - castopod-db
+        volumes:
+          - castopod-db:/var/lib/mysql
+        environment:
+          MYSQL_ROOT_PASSWORD: changeme
+          MYSQL_DATABASE: castopod
+          MYSQL_USER: castopod
+          MYSQL_PASSWORD: changeme
+        restart: unless-stopped
+
+      redis:
+        image: redis:7.0-alpine
+        container_name: "castopod-redis"
+        command: --requirepass changeme
+        volumes:
+          - castopod-cache:/data
+        networks:
+          - castopod-app
+
+    volumes:
+      castopod-media:
+      castopod-db:
+      castopod-cache:
+
+    networks:
+      castopod-app:
+      castopod-db:
+    ```
+
+    You have to adapt some variables to your needs (e.g. `CP_BASEURL`,
+    `MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD` and `CP_ANALYTICS_SALT`).
+
+3.  Setup a reverse proxy for TLS (SSL/HTTPS)
+
+    TLS is mandatory for ActivityPub to work. This job can easily be handled by
+    a reverse proxy, for example with [Caddy](https://caddyserver.com/):
+
+    ```
+    #castopod
+    castopod.example.com {
+        reverse_proxy localhost:8000
+    }
+    ```
+
+4.  Run `docker-compose up -d`, wait for it to initialize and head on to
+    `https://castopod.example.com/cp-install` to finish setting up Castopod!
+
+5.  You're all set, start podcasting! 🎙️🚀
+
+## Environment Variables
+
+- **castopod/castopod** and **castopod/app**
+
+  | Variable name                         | Type (`default`)        | Default          |
+  | ------------------------------------- | ----------------------- | ---------------- |
+  | **`CP_BASEURL`**                      | string                  | `undefined`      |
+  | **`CP_MEDIA_BASEURL`**                | ?string                 | `CP_BASEURL`     |
+  | **`CP_ADMIN_GATEWAY`**                | ?string                 | `"cp-admin"`     |
+  | **`CP_AUTH_GATEWAY`**                 | ?string                 | `"cp-auth"`      |
+  | **`CP_ANALYTICS_SALT`**               | string                  | `undefined`      |
+  | **`CP_DATABASE_HOSTNAME`**            | ?string                 | `"mariadb"`      |
+  | **`CP_DATABASE_NAME`**                | ?string                 | `MYSQL_DATABASE` |
+  | **`CP_DATABASE_USERNAME`**            | ?string                 | `MYSQL_USER`     |
+  | **`CP_DATABASE_PASSWORD`**            | ?string                 | `MYSQL_PASSWORD` |
+  | **`CP_DATABASE_PREFIX`**              | ?string                 | `"cp_"`          |
+  | **`CP_CACHE_HANDLER`**                | [`"file"` or `"redis"`] | `"file"`         |
+  | **`CP_REDIS_HOST`**                   | ?string                 | `"localhost"`    |
+  | **`CP_REDIS_PASSWORD`**               | ?string                 | `null`           |
+  | **`CP_REDIS_PORT`**                   | ?number                 | `6379`           |
+  | **`CP_REDIS_DATABASE`**               | ?number                 | `0`              |
+  | **`CP_EMAIL_SMTP_HOST`**              | ?string                 | `undefined`      |
+  | **`CP_EMAIL_FROM`**                   | ?string                 | `undefined`      |
+  | **`CP_EMAIL_SMTP_USERNAME`**          | ?string                 | `"localhost"`    |
+  | **`CP_EMAIL_SMTP_PASSWORD`**          | ?string                 | `null`           |
+  | **`CP_EMAIL_SMTP_PORT`**              | ?number                 | `25`             |
+  | **`CP_EMAIL_SMTP_CRYPTO`**            | [`"tls"` or `"ssl"`]    | `"tls"`          |
+  | **`CP_ENABLE_2FA`**                   | ?boolean                | `undefined`      |
+  | **`CP_MEDIA_FILE_MANAGER`**           | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_ENDPOINT`**            | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_KEY`**                 | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_SECRET`**              | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_REGION`**              | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_BUCKET`**              | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_PROTOCOL`**            | ?number                 | `undefined`      |
+  | **`CP_MEDIA_S3_PATH_STYLE_ENDPOINT`** | ?boolean                | `undefined`      |
+  | **`CP_MEDIA_S3_KEY_PREFIX`**          | ?string                 | `undefined`      |
+  | **`CP_DISABLE_HTTPS`**                | ?[`0` or `1`]           | `undefined`      |
+  | **`CP_MAX_BODY_SIZE`**                | ?number (with suffix)   | `512M`           |
+  | **`CP_PHP_MEMORY_LIMIT`**             | ?number (with suffix)   | `512M`           |
+  | **`CP_TIMEOUT`**                      | ?number                 | `900`            |
+
+- **castopod/web-server**
+
+  | Variable name          | Type                  | Default |
+  | ---------------------- | --------------------- | ------- |
+  | **`CP_APP_HOSTNAME`**  | ?string               | `"app"` |
+  | **`CP_MAX_BODY_SIZE`** | ?number (with suffix) | `512M`  |
+  | **`CP_TIMEOUT`**       | ?number               | `900`   |
diff --git a/docs/src/eu/getting-started/install.md b/docs/src/eu/getting-started/install.md
new file mode 100644
index 00000000..cdea18ec
--- /dev/null
+++ b/docs/src/eu/getting-started/install.md
@@ -0,0 +1,238 @@
+---
+title: Installation
+sidebarDepth: 3
+---
+
+# How to install Castopod?
+
+Castopod was thought-out to be easy to install. Whether using dedicated or
+shared hosting, you can install it on most PHP-MySQL compatible web servers.
+
+::: tip Note
+
+We've released official Docker images for Castopod!
+
+If you prefer using Docker, you may skip this and go straight to the
+[docker documentation](./docker.md) for Castopod.
+
+:::
+
+## Requirements
+
+- PHP v8.1 or higher
+- MySQL version 5.7 or higher or MariaDB version 10.2 or higher
+- HTTPS support
+- An [ntp-synced clock](https://wiki.debian.org/NTP) to validate federation's
+  incoming requests
+
+### PHP v8.1 or higher
+
+PHP version 8.1 or higher is required, with the following extensions installed:
+
+- [intl](https://php.net/manual/en/intl.requirements.php)
+- [libcurl](https://php.net/manual/en/curl.requirements.php)
+- [mbstring](https://php.net/manual/en/mbstring.installation.php)
+- [gd](https://www.php.net/manual/en/image.installation.php) with **JPEG**,
+  **PNG** and **WEBP** libraries.
+- [exif](https://www.php.net/manual/en/exif.installation.php)
+
+Additionally, make sure that the following extensions are enabled in your PHP:
+
+- json (enabled by default - don't turn it off)
+- xml (enabled by default - don't turn it off)
+- [mysqlnd](https://php.net/manual/en/mysqlnd.install.php)
+
+### MySQL compatible database
+
+> We recommend using [MariaDB](https://mariadb.org).
+
+::: warning Warning
+
+Castopod only works with supported MySQL 5.7 or higher compatible databases. It
+will break with the previous MySQL v5.6 for example as its end of life was on
+February 5, 2021.
+
+:::
+
+You will need the server hostname, database name, username and password to
+complete the installation process. If you do not have these, please contact your
+server administrator.
+
+#### Privileges
+
+User must have at least these privileges on the database for Castopod to work:
+`CREATE`, `ALTER`, `DELETE`, `EXECUTE`, `INDEX`, `INSERT`, `SELECT`, `UPDATE`,
+`REFERENCES`, `CREATE VIEW`.
+
+### (Optional) FFmpeg v4.1.8 or higher for Video Clips
+
+[FFmpeg](https://www.ffmpeg.org/) version 4.1.8 or higher is required if you
+want to generate Video Clips. The following extensions must be installed:
+
+- **FreeType 2** library for
+  [gd](https://www.php.net/manual/en/image.installation.php).
+
+### (Optional) Other recommendations
+
+- Redis for better cache performances.
+- CDN for static files caching and better performances.
+- e-mail gateway for lost passwords.
+
+## Install instructions
+
+### Pre-requisites
+
+0. Get a Web Server with [requirements](#requirements) installed
+1. Create a MySQL database for Castopod with a user having access and
+   modification privileges (for more info, see
+   [MySQL compatible database](#mysql-compatible-database)).
+2. Activate HTTPS on your domain with an _SSL certificate_.
+3. Download and unzip the latest [Castopod Package](https://castopod.org/) onto
+   the web server if you haven’t already.
+   - ⚠️ Set the web server document root to the `public/` sub-folder within the
+     `castopod` folder.
+4. Add **cron tasks** on your web server for various background processes
+   (replace the paths accordingly):
+
+   ```bash
+      * * * * * /path/to/php /path/to/castopod/spark tasks:run >> /dev/null 2>&1
+   ```
+
+   **Note** - If you do not add this cron task, the following Castopod features
+   will not work:
+
+   - Importing a podcast from an existing RSS feed
+   - Broadcasting social activities to your followers in the fediverse
+   - Broadcasting episodes to open hubs using
+     [WebSub](https://en.wikipedia.org/wiki/WebSub)
+   - Generating video clips -
+     [requires FFmpeg](#optional-ffmpeg-v418-or-higher-for-video-clips)
+
+### (recommended) Install Wizard
+
+1. Run the Castopod install script by going to the install wizard page
+   (`https://your_domain_name.com/cp-install`) in your favorite web browser.
+2. Follow the instructions on your screen.
+3. Start podcasting!
+
+::: info Note
+
+The install script writes a `.env` file in the package root. If you cannot go
+through the install wizard, you can create and edit the `.env` file manually
+based on the `.env.example` file.
+
+:::
+
+### Using CLI
+
+1. Create a `.env` file in the package root based on the `.env.example` file.
+2. Initialize the database using:
+
+   ```sh
+   php spark install:init-database
+   ```
+
+3. Create the superadmin user using:
+
+   ```sh
+   php spark install:create-superadmin
+   ```
+
+4. Head on to your admin gateway to start podcasting!
+
+### Email/SMTP setup
+
+Email configuration is required for some features to work properly (eg.
+retrieving your forgotten password, sending instructions to premium subscribers,
+…)
+
+You may add your email configuration in your instance's `.env` like so:
+
+```ini
+# […]
+
+email.fromEmail="your_email_address"
+email.SMTPHost="your_smtp_host"
+email.SMTPUser="your_smtp_user"
+email.SMTPPass="your_smtp_password"
+```
+
+#### Email config options
+
+| Variable name    | Type                 | Default      |
+| ---------------- | -------------------- | ------------ |
+| **`fromEmail`**  | string               | `undefined`  |
+| **`fromName`**   | string               | `"Castopod"` |
+| **`SMTPHost`**   | string               | `undefined`  |
+| **`SMTPUser`**   | string               | `undefined`  |
+| **`SMTPPass`**   | string               | `undefined`  |
+| **`SMTPPort`**   | number               | `25`         |
+| **`SMTPCrypto`** | [`"tls"` or `"ssl"`] | `"tls"`      |
+
+### Media storage
+
+By default, files are saved to the `public/media` folder using the file system.
+If you need to relocate the `media` folder to a different location, you can
+specify it in your `.env` file as shown below:
+
+```ini
+# […]
+
+media.root="media"
+media.storage="/mnt/storage"
+```
+
+In this example, the files will be saved to the /mnt/storage/media folder. Make
+sure to also update your web server configuration to reflect this change.
+
+### S3
+
+If you prefer storing your media files on an S3 compatible storage, you may
+specify it in your `.env`:
+
+```ini
+# […]
+
+media.fileManager="s3"
+media.s3.endpoint="your_s3_host"
+media.s3.key="your_s3_key"
+media.s3.secret="your_s3_secret"
+media.s3.region="your_s3_region"
+```
+
+#### S3 config options
+
+| Variable name           | Type    | Default     |
+| ----------------------- | ------- | ----------- |
+| **`endpoint`**          | string  | `undefined` |
+| **`key`**               | string  | `undefined` |
+| **`secret`**            | string  | `undefined` |
+| **`region`**            | string  | `undefined` |
+| **`bucket`**            | string  | `castopod`  |
+| **`protocol`**          | number  | `undefined` |
+| **`pathStyleEndpoint`** | boolean | `false`     |
+| **`keyPrefix`**         | string  | `undefined` |
+
+## Community packages
+
+If you don't want to bother with installing Castopod manually, you may use one
+of the packages created and maintained by the open-source community.
+
+### Install with YunoHost
+
+[YunoHost](https://yunohost.org/) is a distribution based on Debian GNU/Linux
+made up of free and open-source software packages. It manages the hardships of
+self-hosting for you.
+
+<div class="flex flex-wrap items-center gap-4">
+
+<a href="https://install-app.yunohost.org/?app=castopod" target="_blank" rel="noopener noreferrer">
+   <img src="https://install-app.yunohost.org/install-with-yunohost.svg" alt="Install Castopod with YunoHost" class="align-middle" />
+</a>
+
+<a href="https://github.com/YunoHost-Apps/castopod_ynh" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-4 py-[.3rem] mx-auto font-semibold text-center text-black rounded-md gap-x-1 border-2 border-solid border-[#333] hover:no-underline hover:bg-gray-100"><svg
+   xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1em" height="1em"
+   class="text-xl"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 2A10 10 0 0 0 2 12a10 10 0 0 0 6.84 9.49c.5.09.69-.21.69-.48l-.02-1.86c-2.51.46-3.16-.61-3.36-1.18-.11-.28-.6-1.17-1.02-1.4-.35-.2-.85-.66-.02-.67.79-.01 1.35.72 1.54 1.02.9 1.52 2.34 1.1 2.91.83a2.1 2.1 0 0 1 .64-1.34c-2.22-.25-4.55-1.11-4.55-4.94A3.9 3.9 0 0 1 6.68 8.8a3.6 3.6 0 0 1 .1-2.65s.83-.27 2.75 1.02a9.28 9.28 0 0 1 2.5-.34c.85 0 1.7.12 2.5.34 1.9-1.3 2.75-1.02 2.75-1.02.54 1.37.2 2.4.1 2.65.63.7 1.02 1.58 1.02 2.68 0 3.84-2.34 4.7-4.56 4.94.36.31.67.91.67 1.85l-.01 2.75c0 .26.19.58.69.48A10.02 10.02 0 0 0 22 12 10 10 0 0 0 12 2z"/></svg>Github
+Repo</a>
+
+</div>
diff --git a/docs/src/eu/getting-started/security.md b/docs/src/eu/getting-started/security.md
new file mode 100644
index 00000000..e205698d
--- /dev/null
+++ b/docs/src/eu/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/eu/getting-started/update.md b/docs/src/eu/getting-started/update.md
new file mode 100644
index 00000000..98e019fb
--- /dev/null
+++ b/docs/src/eu/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/eu/index.md b/docs/src/eu/index.md
new file mode 100644
index 00000000..b63ff645
--- /dev/null
+++ b/docs/src/eu/index.md
@@ -0,0 +1,300 @@
+---
+sidebarDepth: 2
+---
+
+# Welcome 👋
+
+[![release-badge]][release]&nbsp;[![license-badge]][license]&nbsp;[![contributions-badge]][contributions]&nbsp;[![semantic-release-badge]][semantic-release]&nbsp;[![crowdin-badge]][crowdin]&nbsp;[![discord-badge]][discord]&nbsp;[![stars-badge]][stars]
+
+Castopod is a free & open-source hosting platform made for podcasters who want
+engage and interact with their audience.
+
+Castopod is easy to install and was built on top of
+[CodeIgniter4](https://codeigniter.com/), a powerful PHP framework with a very
+small footprint.
+
+<div class="flex items-center">
+  <a href="/getting-started/install" class="inline-flex items-center px-4 py-2 mx-auto font-semibold text-center text-white rounded-full shadow gap-x-1 bg-pine-500 hover:no-underline hover:bg-pine-600">Install<svg viewBox="0 0 24 24" width="1em" height="1em" class="text-xl text-pine-200"><path fill="currentColor" d="m16.172 11-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z"></path></svg></a>
+</div>
+
+## Features
+
+- 🌱 &nbsp;Free & open-source (AGPL v3 License)
+- 🔐 &nbsp;Focused on data sovereignty: your content, audience, and analytics
+  belong to you, and&nbsp;you&nbsp;only
+- 🪄 &nbsp;Podcasting 2.0 features: GUID, locked, transcripts, funding,
+  chapters, location, persons, soundbites, …
+- 💬 &nbsp;Built-in social network:
+  - 🚀 &nbsp;Castopod is part of the Fediverse, a decentralized social network
+  - ❤️ &nbsp;Create posts, share, favourite, and comment on episodes
+- 📈 &nbsp;Built-in analytics:
+  - ⚖️ &nbsp;GDPR / CCPA / LGPD compliant
+  - 🪙 &nbsp;Standard IABv2 audience measurement
+  - 🏡 &nbsp;On-premises analytics, no third party involved
+- 📢 &nbsp;Built-in marketing tools:
+  - ✅ &nbsp;SEO ready (open-graph meta-tags, JSON-LD, …)
+  - 📱 &nbsp;PWA: install as a standalone app
+  - 🎨 &nbsp;Customizable theme colors
+  - 🎬 &nbsp;Generate ready-to-share Video clips from episodes
+  - 🔉 &nbsp;Generate soundbites
+  - ▶️ &nbsp;Embeddable player, embed your episodes on any website
+- 💸 &nbsp;Monetization:
+  - 🔗 &nbsp;Funding links
+  - 📲 &nbsp;listen-to-click ads
+  - 🤝 &nbsp;value4value / WebMonetization
+  - 💎 &nbsp;Premium podcasts
+- 📡 &nbsp;Publish your episodes everywhere with RSS:
+  - 📱 &nbsp;On all indexes and apps: Podcast Index, Apple Podcasts, Spotify,
+    Google Podcasts, Deezer, Podcast Addict, Podfriend, …
+  - ⚡ &nbsp;Broadcast your episodes instantly with WebSub
+- 📥 &nbsp;Podcast import: move your existing podcast into Castopod
+- 📤 &nbsp;Move your podcast out of Castopod
+- 🔀 &nbsp;Multi-tenant: host as many podcasts as you want
+- 👥 &nbsp;Multi-user: add contributors and set roles
+- 🌎 &nbsp;i18n support: translated in English, French, Polish, German,
+  Brazilian Portuguese & Spanish… with
+  [more to come](https://translate.castopod.org)!
+
+## Motivation
+
+The podcasting ecosystem is decentralized by nature: you can create your podcast
+as an RSS file, publish it on the web and have it shared everywhere online.
+
+It is in fact one of the only media to have stayed this way for a long time.
+
+As usages are evolving, more and more people are getting into podcasts: whether
+it is creators finding new ways to share their ideas, or listeners in the search
+for better content.
+
+With podcasting becoming more widely used, some companies are trying to shift it
+towards a more controlled and centralized medium.
+
+Castopod was created in an effort to provide an open and sustainable alternative
+to hosting your podcasts, promoting decentralization to ensure that podcasters
+creativity can express itself.
+
+This project is pushed by the open-source community, and specifically by the
+[Fediverse](https://fediverse.party/en/fediverse/) and
+[Podcasting 2.0](https://podcastindex.org/) movements.
+
+## Comparison with other solutions
+
+We believe that a solution is not necessarily right for everyone, it highly
+depends on your needs. So, here are comparisons with other tools to help you to
+gauge whether Castopod is the right fit for&nbsp;you.
+
+### Castopod vs Wordpress
+
+Castopod is often referred to as "the Wordpress for podcasts" because of the
+similarities between the two. In some ways this is true. And actually, Castopod
+was greatly inspired by the Wordpress ecosystem, seeing the ease of adoption
+from the community and the number of websites running&nbsp;it.
+
+Just like Wordpress, Castopod is free & open source, built using PHP with a
+MySQL database and is packaged in a way that you can easily install on most web
+servers.
+
+Wordpress is a great way to create your website and extend it with plugins to
+get what you want. It is a full fledged CMS that helps you get any type of
+website online.
+
+On the other hand, Castopod is meant to address the podcasters needs
+specifically, focusing on podcasting, and nothing else. You don't need any
+plugin to get you started on your podcasting&nbsp;journey.
+
+This allows optimizing the processes specific to podcasting: ranging from the
+creation of your podcasts and the publication of new episodes all the way to
+broadcasting, marketing and analytics.
+
+Finally, depending on your needs, Wordpress and Castopod can even live side by
+side as they share the same requirements!
+
+### Castopod vs Funkwhale
+
+Funkwhale is a self-hosted, modern free and open-source music server. Just as
+Castopod, Funkwhale is on the fediverse, a decentralized social network allowing
+interoperability between the two.
+
+Funkwhale was initially built around music. And later on, as the project
+evolved, the ability to host podcasts was introduced.
+
+Unlike Funkwhale, Castopod has been designed and built around podcasting
+exclusively. This allows easier implementation for features related to the
+podcasting ecosystem, such as the podcasting 2.0 features (transcripts,
+chapters, locations, persons, …).
+
+So, you should probably use Funkwhale if you want to host your music, and use
+Castopod if you want to host your podcasts.
+
+### Castopod vs other podcast hosts
+
+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!
+
+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:
+
+- Castopod can be self-hosted and is the only solution that allows you to keep
+  full control over what you produce. Also, as it is open-source, you can even
+  customize it as you wish.
+
+- Castopod is the only solution that currently integrates both a decentralized
+  social network with ActivityPub as well as many of the podcasting 2.0
+  features, hoping to bridge the gap between the two.
+
+## Contributing
+
+Love Castopod and would like to help? Take a look at the following documentation
+to get you&nbsp;started.
+
+### Code of conduct
+
+Castopod has adopted a Code of Conduct that we expect project participants to
+adhere to. Please read the
+[CODE_OF_CONDUCT manual](https://code.castopod.org/adaures/castopod/-/blob/beta/CODE_OF_CONDUCT.md)
+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
+development process, how to propose bugfixes and improvements, and how to build
+and test your changes to Castopod.
+
+## Contributors ✨
+
+Thanks goes to these wonderful people
+([emoji key](https://allcontributors.org/docs/en/emoji-key)):
+
+<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
+<!-- prettier-ignore-start -->
+<!-- markdownlint-disable -->
+<table>
+  <tbody>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/yassinedoghri"><img src="https://code.castopod.org/uploads/-/system/user/avatar/3/avatar.png?s=100" width="100px;" alt="Yassine Doghri"/><br /><sub><b>Yassine Doghri</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/issues?author_username=yassinedoghri" title="Bug reports">🐛</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Documentation">📖</a> <a href="https://code.castopod.org/adaures/castopod/merge_requests?scope=all&state=all&approver_usernames[]=yassinedoghri" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-yassinedoghri" title="Maintenance">🚧</a> <a href="#content-yassinedoghri" title="Content">🖋</a> <a href="#design-yassinedoghri" title="Design">🎨</a> <a href="#a11y-yassinedoghri" title="Accessibility">️️️️♿️</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#question-yassinedoghri" title="Answering Questions">💬</a> <a href="#mentoring-yassinedoghri" title="Mentoring">🧑‍🏫</a> <a href="#infra-yassinedoghri" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-yassinedoghri" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-yassinedoghri" title="Project Management">📆</a> <a href="https://blog.castopod.org/author/yassinedoghri/" title="Blogposts">📝</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/benjamin"><img src="https://code.castopod.org/uploads/-/system/user/avatar/2/avatar.png?s=100" width="100px;" alt="Benjamin Bellamy"/><br /><sub><b>Benjamin Bellamy</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/issues?author_username=benjamin" title="Bug reports">🐛</a> <a href="https://code.castopod.org/adaures/castopod/merge_requests?scope=all&state=all&approver_usernames[]=benjamin" title="Reviewed Pull Requests">👀</a> <a href="#content-benjamin" title="Content">🖋</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#question-benjamin" title="Answering Questions">💬</a> <a href="#infra-benjamin" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-benjamin" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://blog.castopod.org/author/benjamin-bellamy/" title="Blogposts">📝</a> <a href="#projectManagement-benjamin" title="Project Management">📆</a> <a href="#talk-benjamin" title="Talks">📢</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/ola-hn"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Ola Hneini"/><br /><sub><b>Ola Hneini</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/merge_requests?scope=all&state=all&approver_usernames[]=ola" title="Reviewed Pull Requests">👀</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Documentation">📖</a> <a href="#maintenance-ola" title="Maintenance">🚧</a> <a href="#question-ola" title="Answering Questions">💬</a> <a href="#ideas-ola" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://mamot.fr/@rdelaage"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Romain de Laage"/><br /><sub><b>Romain de Laage</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="#infra-rdelaage" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Documentation">📖</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#ideas-rdelaage" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/lyonelbernard"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Lyonel Bernard"/><br /><sub><b>Lyonel Bernard</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=Lyonel" title="Bug reports">🐛</a> <a href="#question-Lyonel" title="Answering Questions">💬</a> <a href="#audio-Lyonel" title="Audio">🔊</a> <a href="#ideas-Lyonel" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://www.crypticchameleon.com/"><img src="https://secure.gravatar.com/avatar/7c2a721b52d0763673a600e8f01bd745?s=80&d=identicon?s=100" width="100px;" alt="Christopher Lagonick-Weitzel"/><br /><sub><b>Christopher Lagonick-Weitzel</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=ctlw83" title="Bug reports">🐛</a> <a href="#question-ctlw83" title="Answering Questions">💬</a> <a href="#audio-ctlw83" title="Audio">🔊</a> <a href="#ideas-ctlw83" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://ernestoacosta.me/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Ernesto Acosta"/><br /><sub><b>Ernesto Acosta</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=ernestoacostame" title="Bug reports">🐛</a> <a href="#audio-ernestoacostame" title="Audio">🔊</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#question-ernestoacostame" title="Answering Questions">💬</a> <a href="#ideas-ernestoacostame" title="Ideas, Planning, & Feedback">🤔</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://mastodon.fedi.bzh/@ewen"><img src="https://mastodon.fedi.bzh/system/accounts/avatars/000/000/002/original/6f387690a504ae46.jpg?s=100" width="100px;" alt="Ewen"/><br /><sub><b>Ewen</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#ideas-3wen" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/Behel"><img src="https://secure.gravatar.com/avatar/ad63ee8ef8e3db8253d21e5012d2724f?s=80&d=identicon?s=100" width="100px;" alt="Bastien Luneteau"/><br /><sub><b>Bastien Luneteau</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/issues?author_username=Behel" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://www.cecillie.fr/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Cécile Ricordeau"/><br /><sub><b>Cécile Ricordeau</b></sub></a><br /><a href="#design-cecillie" title="Design">🎨</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/PatrykMis"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Patryk Miś"/><br /><sub><b>Patryk Miś</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/mspanc"><img src="https://secure.gravatar.com/avatar/eed8337939641eac5ad0b570bd6acf96?s=80&d=identicon?s=100" width="100px;" alt="Marcin Lewandowski"/><br /><sub><b>Marcin Lewandowski</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=mspanc" title="Bug reports">🐛</a> <a href="#ideas-mspanc" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/SJanik"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Sebastian Janik"/><br /><sub><b>Sebastian Janik</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/patryk"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Patryk Karczmarczyk"/><br /><sub><b>Patryk Karczmarczyk</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/ddenis"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="denis d"/><br /><sub><b>denis d</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=ddenis" title="Bug reports">🐛</a> <a href="#ideas-ddenis" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/douglaskastle"><img src="https://secure.gravatar.com/avatar/b7e652ba4b6bcd440afa069e7f7bc9e6?s=80&d=identicon?s=100" width="100px;" alt="Douglas Kastle"/><br /><sub><b>Douglas Kastle</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=douglaskastle" title="Bug reports">🐛</a> <a href="#ideas-douglaskastle" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/cExplorer"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="cExplorer"/><br /><sub><b>cExplorer</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=cExplorer" title="Bug reports">🐛</a> <a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/imacrea"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="ImaCrea"/><br /><sub><b>ImaCrea</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=imacrea" title="Bug reports">🐛</a> <a href="#ideas-imacrea" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/jonas"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Jonas S"/><br /><sub><b>Jonas S</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/yannL"><img src="https://secure.gravatar.com/avatar/9c46600ce566ec6d526370d8e104b1c8?s=80&d=identicon?s=100" width="100px;" alt="LEFEBVRE Yann"/><br /><sub><b>LEFEBVRE Yann</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=yannL" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/spaetz"><img src="https://secure.gravatar.com/avatar/278e1af65e82993efd0ba7bbbacf6435?s=80&d=identicon?s=100" width="100px;" alt="Sebastian Späth"/><br /><sub><b>Sebastian Späth</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=spaetz" title="Bug reports">🐛</a> <a href="#ideas-spaetz" title="Ideas, Planning, & Feedback">🤔</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/rocky"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="rocky III"/><br /><sub><b>rocky III</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=rocky" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/Regenpfeifer"><img src="https://code.castopod.org/uploads/-/system/user/avatar/103/avatar.png?s=100" width="100px;" alt="Hermann Josef Eckl"/><br /><sub><b>Hermann Josef Eckl</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=Regenpfeifer" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/cyrilledel"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Delhaye Cyrille"/><br /><sub><b>Delhaye Cyrille</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=cyrilledel" title="Bug reports">🐛</a> <a href="#ideas-cyrilledel" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/otetranome"><img src="https://code.castopod.org/uploads/-/system/user/avatar/113/avatar.png?s=100" width="100px;" alt="João Leandro"/><br /><sub><b>João Leandro</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#ideas-otetranome" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://achouvardas.eu/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Angelos Chouvardas"/><br /><sub><b>Angelos Chouvardas</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://mastodon.fjerland.no/@eivind"><img src="https://mastodon.fjerland.no/system/accounts/avatars/107/769/768/295/192/222/original/e5c985fea6487dcb.jpg?s=100" width="100px;" alt="Eivind"/><br /><sub><b>Eivind</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/forght"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15073833/large/82d1e2e443a6df7edc43a7405dfeeb75_default.png?s=100" width="100px;" alt="forght"/><br /><sub><b>forght</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/glottis0q"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15209934/large/8b17ef6a7399f0b82a8198f87c224195.png?s=100" width="100px;" alt="glottis0q"/><br /><sub><b>glottis0q</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://mstdn.fr/@ButterflyOfFire"><img src="https://static.mstdn.fr/static/accounts/avatars/000/065/901/original/5908e93ad5447f15.png?s=100" width="100px;" alt="ButterflyOfFire"/><br /><sub><b>ButterflyOfFire</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/lil5"><img src="https://avatars.githubusercontent.com/u/17646836?v=4?s=100" width="100px;" alt="Lucian I. Last"/><br /><sub><b>Lucian I. Last</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/luuzviir"><img src="https://crowdin-static.downloads.crowdin.com/avatar/13166188/large/d03ab0abc7ce354b210d836955cd3805_default.png?s=100" width="100px;" alt="LuuzViir"/><br /><sub><b>LuuzViir</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/cthtc"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15211502/large/ed0651060cb8474a9519b5168bd377c1_default.png?s=100" width="100px;" alt="CTHTC"/><br /><sub><b>CTHTC</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/retrograde"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15021651/large/b10c4057f85bf4de49c7fdf01354ecde.jpeg?s=100" width="100px;" alt="Russian Retro"/><br /><sub><b>Russian Retro</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/mareklach"><img src="https://crowdin-static.downloads.crowdin.com/avatar/13572324/large/3eeba8d569c247ace33862bf4ef4748f.jpeg?s=100" width="100px;" alt="Marek L'ach"/><br /><sub><b>Marek L'ach</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/gunchleoc"><img src="https://crowdin-static.downloads.crowdin.com/avatar/13043878/large/3223f7b606296a8b1c92c5de39c459a2_default.png?s=100" width="100px;" alt="GunChleoc"/><br /><sub><b>GunChleoc</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/gabisnow"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15214858/large/5b083bdf9c9e9de67cc6ee72a6c8db18_default.png?s=100" width="100px;" alt="GabiSnow"/><br /><sub><b>GabiSnow</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/bendaha"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15331656/large/cd92450d2c20202299fb3a0075903e20_default.png?s=100" width="100px;" alt="bendaha"/><br /><sub><b>bendaha</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/samuelroland"><img src="https://crowdin-static.downloads.crowdin.com/avatar/14980053/large/3e154a37d03d6e98ae402ed3f930f4f5.png?s=100" width="100px;" alt="Samuel Roland"/><br /><sub><b>Samuel Roland</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://dimitriregnier.net/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Dimitri Regnier"/><br /><sub><b>Dimitri Regnier</b></sub></a><br /><a href="#ideas-dimregnier" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://im.irithys.com/@thy"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15405614/large/3086461c47cce0a0c031925e5f943412.png?s=100" width="100px;" alt="irithys"/><br /><sub><b>irithys</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/caos30"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Sergi"/><br /><sub><b>Sergi</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/xosem"><img src="https://crowdin-static.downloads.crowdin.com/avatar/12617257/large/a201650da44fed28890b0e0d8477a663.jpg?s=100" width="100px;" alt="ghose (XoseM)"/><br /><sub><b>ghose (XoseM)</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/basen1982"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Andreas Olsson"/><br /><sub><b>Andreas Olsson</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/leonfrom"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="leonfrom"/><br /><sub><b>leonfrom</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/agentcobra57"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="agentcobra"/><br /><sub><b>agentcobra</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/alephoto85"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15094649/large/530391f54157af52ae33058ec15b0f99.jpg?s=100" width="100px;" alt="Alessandro"/><br /><sub><b>Alessandro</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/liimee"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="liimee"/><br /><sub><b>liimee</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/ahmedsabouni"><img src="https://avatars.githubusercontent.com/u/74497842?v=4?s=100" width="100px;" alt="Ahmed Sabouni"/><br /><sub><b>Ahmed Sabouni</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/KrzysztofDomanczyk"><img src="https://avatars.githubusercontent.com/u/75178474?v=4?s=100" width="100px;" alt="KrzysztofDomanczyk"/><br /><sub><b>KrzysztofDomanczyk</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/NeoluxConsulting"><img src="https://secure.gravatar.com/avatar/6e745565356330c1e29a85d52bffdaa1?s=80&d=identicon?s=100" width="100px;" alt="Guy Martin"/><br /><sub><b>Guy Martin</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=NeoluxConsulting" title="Bug reports">🐛</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+    </tr>
+  </tbody>
+</table>
+
+<!-- markdownlint-restore -->
+<!-- prettier-ignore-end -->
+
+<!-- ALL-CONTRIBUTORS-LIST:END -->
+
+This project follows the
+[all-contributors](https://github.com/all-contributors/all-contributors)
+specification. Contributions of any kind welcome!
+
+## Contact
+
+You may reach us for help or ask any question you have on:
+
+- [Discord](https://castopod.org/discord) (for direct interaction with
+  developers and the community)
+- [Issue tracker](https://code.castopod.org/adaures/castopod/-/issues) (for
+  feature requests & bug reports)
+
+Alternatively, you can follow us on social media platforms to get news about
+Castopod:
+
+- [podlibre.social](https://podlibre.social/@Castopod) (Mastodon instance)
+- [Twitter](https://twitter.com/castopod)
+- [LinkedIn](https://linkedin.com/company/castopod)
+- [Facebook](https://www.facebook.com/castopod)
+
+## Sponsors
+
+The ongoing development of Castopod is made possible with the support of its
+backers. If you'd like to help, please consider
+[sponsoring Castopod's development](https://opencollective.com/castopod/contribute).
+
+<div class="flex flex-wrap gap-x-16 gap-y-8">
+  <a href="https://adaures.com/" target="_blank" rel="noopener noreferrer"><img src="/images/sponsors/adaures.svg" alt="Ad Aures Logo" class="h-16" /></a>
+  <a href="https://nlnet.nl/project/Castopod/" target="_blank" rel="noopener noreferrer"><img src="/images/sponsors/nlnet.svg" alt="NLnet Logo" class="h-16" /></a>
+</div>
+
+## License
+
+[GNU Affero General Public License v3.0](https://choosealicense.com/licenses/agpl-3.0/)
+
+Copyright © 2020-present, [Ad Aures](https://adaures.com/).
+https://img.shields.io/gitlab/v/release/2?color=brightgreen&gitlab_url=https%3A%2F%2Fcode.castopod.org%2F&include_prereleases&label=release
+https://img.shields.io/github/license/ad-aures/castopod?color=blue
+https://img.shields.io/badge/contributions-welcome-brightgreen.svg
+https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
+https://img.shields.io/github/stars/ad-aures/castopod?style=social
+
+[release]: https://code.castopod.org/adaures/castopod/-/releases
+[license]: https://code.castopod.org/adaures/castopod/-/blob/beta/LICENSE.md
+[contributions]: https://code.castopod.org/adaures/castopod/-/issues
+[semantic-release]: https://github.com/semantic-release/semantic-release
+[discord]: https://castopod.org/discord
+[stars]: https://github.com/ad-aures/castopod/stargazers
+[crowdin]: https://translate.castopod.org/project/castopod
diff --git a/docs/src/fa/getting-started/docker.md b/docs/src/fa/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/fa/getting-started/docker.md
+++ b/docs/src/fa/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/fr/getting-started/docker.md b/docs/src/fr/getting-started/docker.md
index b8d58bf0..6419825e 100644
--- a/docs/src/fr/getting-started/docker.md
+++ b/docs/src/fr/getting-started/docker.md
@@ -32,31 +32,32 @@ de données Redis peut être ajoutée en tant que gestionnaire de cache.
 2.  Créez un fichier `docker-compose.yml` avec les éléments suivants :
 
     ```yml
-    version: "3.
+    version: "3.7"
 
-    services :
+    services:
       app:
         image: castopod/castopod:latest
         container_name: "castopod-app"
         volumes:
           - castopod-media:/var/www/castopod/public/media
-        environnement:
+        environment:
           MYSQL_DATABASE: castopod
           MYSQL_USER: castopod
           MYSQL_PASSWORD: changeme
-          CP_BASEURL: "https://castopod. xample. om"
-          CP_ANALYTICS_SALT : changer
+          CP_BASEURL: "https://castopod.example.com"
+          CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
-        réseaux :
+          CP_REDIS_PASSWORD: changeme
+        networks:
           - castopod-app
           - castopod-db
-        ports :
+        ports:
           - 8000:8000
-        redémarrage :
+        restart: unless-stopped
 
       mariadb:
-        image: mariadb:10.
+        image: mariadb:10.5
         container_name: "castopod-mariadb"
         networks:
           - castopod-db
@@ -66,15 +67,16 @@ de données Redis peut être ajoutée en tant que gestionnaire de cache.
           MYSQL_ROOT_PASSWORD: changeme
           MYSQL_DATABASE: castopod
           MYSQL_USER: castopod
-          MYSQL_PASSWORD: changez
+          MYSQL_PASSWORD: changeme
         restart: unless-stopped
 
       redis:
-        image: redis:redis:7. -alpine
+        image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
-        réseaux:
+        networks:
           - castopod-app
 
     volumes:
diff --git a/docs/src/fr2/getting-started/docker.md b/docs/src/fr2/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/fr2/getting-started/docker.md
+++ b/docs/src/fr2/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/fr_CA/getting-started/docker.md b/docs/src/fr_CA/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/fr_CA/getting-started/docker.md
+++ b/docs/src/fr_CA/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/gd/getting-started/docker.md b/docs/src/gd/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/gd/getting-started/docker.md
+++ b/docs/src/gd/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/gl/getting-started/docker.md b/docs/src/gl/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/gl/getting-started/docker.md
+++ b/docs/src/gl/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/id/getting-started/docker.md b/docs/src/id/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/id/getting-started/docker.md
+++ b/docs/src/id/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/it/getting-started/docker.md b/docs/src/it/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/it/getting-started/docker.md
+++ b/docs/src/it/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/ja/getting-started/docker.md b/docs/src/ja/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/ja/getting-started/docker.md
+++ b/docs/src/ja/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/kk/getting-started/docker.md b/docs/src/kk/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/kk/getting-started/docker.md
+++ b/docs/src/kk/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/ko/getting-started/docker.md b/docs/src/ko/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/ko/getting-started/docker.md
+++ b/docs/src/ko/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/nl/getting-started/docker.md b/docs/src/nl/getting-started/docker.md
index 23cc9eb9..eb9549d2 100644
--- a/docs/src/nl/getting-started/docker.md
+++ b/docs/src/nl/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/nn-NO/getting-started/docker.md b/docs/src/nn-NO/getting-started/docker.md
index f23732e0..09af9d61 100644
--- a/docs/src/nn-NO/getting-started/docker.md
+++ b/docs/src/nn-NO/getting-started/docker.md
@@ -32,57 +32,59 @@ Redis-database for å handtera mellomlagring.
 2.  Lag ei `docker-compose.yml`-fil som inneheld dette:
 
     ```yml
-    version: "3.7"
+    versjon: "3.7"
 
-    services:
+    tenester:
       app:
-        image: castopod/castopod:latest
-        container_name: "castopod-app"
-        volumes:
+        bilete: castopod/castopod:latest
+        container_namn: "castopod-app"
+        lagringsvolum:
           - castopod-media:/var/www/castopod/public/media
-        environment:
+        miljø:
           MYSQL_DATABASE: castopod
           MYSQL_USER: castopod
-          MYSQL_PASSWORD: changeme
-          CP_BASEURL: "https://castopod.example.com"
-          CP_ANALYTICS_SALT: changeme
+          MYSQL_PASSWORD: endremeg
+          CP_BASEURL: "https://castopod.domene.no"
+          CP_ANALYTICS_SALT: endremeg
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
-        networks:
+          CP_REDIS_PASSWORD: endremeg
+        nettverk:
           - castopod-app
           - castopod-db
-        ports:
+        portar:
           - 8000:8000
         restart: unless-stopped
 
       mariadb:
-        image: mariadb:10.5
-        container_name: "castopod-mariadb"
-        networks:
+        bilete: mariadb:10.5
+        container_namn: "castopod-mariadb"
+        nettverk:
           - castopod-db
-        volumes:
+        lagringsvolum:
           - castopod-db:/var/lib/mysql
-        environment:
-          MYSQL_ROOT_PASSWORD: changeme
+        miljø:
+          MYSQL_ROOT_PASSWORD: endremeg
           MYSQL_DATABASE: castopod
           MYSQL_USER: castopod
-          MYSQL_PASSWORD: changeme
+          MYSQL_PASSWORD: endremeg
         restart: unless-stopped
 
       redis:
-        image: redis:7.0-alpine
-        container_name: "castopod-redis"
-        volumes:
+        bilete: redis:7.0-alpine
+        container_namn: "castopod-redis"
+        kommando: --requirepass changeme
+        lagringsvolum:
           - castopod-cache:/data
-        networks:
+        nettverk:
           - castopod-app
 
-    volumes:
+    lagringsvolum:
       castopod-media:
       castopod-db:
       castopod-cache:
 
-    networks:
+    nettverk:
       castopod-app:
       castopod-db:
     ```
diff --git a/docs/src/oc/getting-started/docker.md b/docs/src/oc/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/oc/getting-started/docker.md
+++ b/docs/src/oc/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/pl/getting-started/docker.md b/docs/src/pl/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/pl/getting-started/docker.md
+++ b/docs/src/pl/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/pt-BR/getting-started/docker.md b/docs/src/pt-BR/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/pt-BR/getting-started/docker.md
+++ b/docs/src/pt-BR/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/pt/getting-started/docker.md b/docs/src/pt/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/pt/getting-started/docker.md
+++ b/docs/src/pt/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/ro/getting-started/docker.md b/docs/src/ro/getting-started/docker.md
index 4de0f4f3..48bb4a19 100644
--- a/docs/src/ro/getting-started/docker.md
+++ b/docs/src/ro/getting-started/docker.md
@@ -48,6 +48,7 @@ Redis poate fi adăugată pentru cache.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ Redis poate fi adăugată pentru cache.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/ru/getting-started/docker.md b/docs/src/ru/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/ru/getting-started/docker.md
+++ b/docs/src/ru/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/sk/getting-started/docker.md b/docs/src/sk/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/sk/getting-started/docker.md
+++ b/docs/src/sk/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/sr-Latn/getting-started/docker.md b/docs/src/sr-Latn/getting-started/docker.md
index b73daca5..edb10c1d 100644
--- a/docs/src/sr-Latn/getting-started/docker.md
+++ b/docs/src/sr-Latn/getting-started/docker.md
@@ -48,6 +48,7 @@ podataka može se dodati kao obrađivač keša.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ podataka može se dodati kao obrađivač keša.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/sv/getting-started/docker.md b/docs/src/sv/getting-started/docker.md
index 762465fb..cb478cf8 100644
--- a/docs/src/sv/getting-started/docker.md
+++ b/docs/src/sv/getting-started/docker.md
@@ -48,6 +48,7 @@ läggas till som cachehanterare.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ läggas till som cachehanterare.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/uk/getting-started/docker.md b/docs/src/uk/getting-started/docker.md
index 75158bd6..12f01619 100644
--- a/docs/src/uk/getting-started/docker.md
+++ b/docs/src/uk/getting-started/docker.md
@@ -48,6 +48,7 @@ can be added as a cache handler.
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -72,6 +73,7 @@ can be added as a cache handler.
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/zh-Hans/getting-started/docker.md b/docs/src/zh-Hans/getting-started/docker.md
index 4e20f7fd..2ffa2369 100644
--- a/docs/src/zh-Hans/getting-started/docker.md
+++ b/docs/src/zh-Hans/getting-started/docker.md
@@ -47,6 +47,7 @@ Castopod 在其自动构建期间会将 3 个 Docker 映像推送到 Docker Hub
           CP_ANALYTICS_SALT: changeme
           CP_CACHE_HANDLER: redis
           CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
         networks:
           - castopod-app
           - castopod-db
@@ -71,6 +72,7 @@ Castopod 在其自动构建期间会将 3 个 Docker 映像推送到 Docker Hub
       redis:
         image: redis:7.0-alpine
         container_name: "castopod-redis"
+        command: --requirepass changeme
         volumes:
           - castopod-cache:/data
         networks:
diff --git a/docs/src/zh-Hant/getting-started/auth.md b/docs/src/zh-Hant/getting-started/auth.md
new file mode 100644
index 00000000..90e50e53
--- /dev/null
+++ b/docs/src/zh-Hant/getting-started/auth.md
@@ -0,0 +1,87 @@
+---
+title: 認證 & 授權
+sidebarDepth: 3
+---
+
+# 認證 & 授權
+
+Castopod 使用 `codeigniter/shield` 處理身分認證和授權 與自定義規則。 腳色和權限
+在定義為兩個層級:
+
+1. [實例範圍](#1-instance-wide-roles-and-permissions)
+2. [每個播客](#2-per-podcast-roles-and-permissions)
+
+## 1. 實例範圍的腳色和權限
+
+### 實例腳色
+
+<!-- AUTH-INSTANCE-ROLES-LIST:START - Do not remove or modify this section -->
+
+| 腳色        | 說明                                | 權限                                                                                       |
+| ----------- | ----------------------------------- | ------------------------------------------------------------------------------------------ |
+| Super admin | Has complete control over Castopod. | admin.\*, podcasts.\*, users.manage, persons.manage, pages.manage, fediverse.manage-blocks |
+| Manager     | Manages Castopod's content.         | podcasts.create, podcasts.import, persons.manage, pages.manage                             |
+| Podcaster   | General users of Castopod.          | admin.access                                                                               |
+
+<!-- AUTH-INSTANCE-ROLES-LIST:END -->
+
+### 實例權限
+
+<!-- AUTH-INSTANCE-PERMISSIONS-LIST:START - Do not remove or modify this section -->
+
+| 權限                    | 說明                                                               |
+| ----------------------- | ------------------------------------------------------------------ |
+| 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. |
+
+<!-- AUTH-INSTANCE-PERMISSIONS-LIST:END -->
+
+## 2. 每個播客腳色與權限
+
+### 每個播客腳色
+
+<!-- AUTH-PODCAST-ROLES-LIST:START - Do not remove or modify this section -->
+
+| 腳色   | 說明                                                      | 權限                                                                                                                                                                                                                                                                                        |
+| ------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Admin  | Has complete control of podcast #{id}.                    | \*                                                                                                                                                                                                                                                                                          |
+| Editor | Manages content and publications of podcast #{id}.        | view, edit, manage-import, manage-persons, manage-platforms, manage-publications, manage-notifications, interact-as, episodes.view, episodes.create, episodes.edit, episodes.delete, episodes.manage-persons, episodes.manage-clips, episodes.manage-publications, episodes.manage-comments |
+| Author | Manages content of podcast #{id} but cannot publish them. | view, manage-persons, episodes.view, episodes.create, episodes.edit, episodes.manage-persons, episodes.manage-clips                                                                                                                                                                         |
+| Guest  | General contributor of the podcast #{id}.                 | view, episodes.view                                                                                                                                                                                                                                                                         |
+
+<!-- AUTH-PODCAST-ROLES-LIST:END -->
+
+### 每個播客權限
+
+<!-- AUTH-PODCAST-PERMISSIONS-LIST:START - Do not remove or modify this section -->
+
+| 權限                         | 說明                                                                     |
+| ---------------------------- | ------------------------------------------------------------------------ |
+| 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 dashboard and analytics of podcast #{id}.                       |
+| episodes.create              | Can create episodes for podcast #{id}.                                   |
+| episodes.edit                | Can edit podcast #{id}.                                                  |
+| episodes.delete              | Can delete podcast #{id}.                                                |
+| episodes.manage-persons      | Can manage subscriptions of podcast #{id}.                               |
+| episodes.manage-clips        | Can manage video clips or soundbites of podcast #{id}.                   |
+| episodes.manage-publications | Can publish podcast #{id}.                                               |
+| episodes.manage-comments     | Can create/remove episode comments of podcast #{id}.                     |
+
+<!-- AUTH-PODCAST-PERMISSIONS-LIST:END -->
diff --git a/docs/src/zh-Hant/getting-started/docker.md b/docs/src/zh-Hant/getting-started/docker.md
new file mode 100644
index 00000000..12f01619
--- /dev/null
+++ b/docs/src/zh-Hant/getting-started/docker.md
@@ -0,0 +1,160 @@
+---
+title: Official Docker images
+sidebarDepth: 3
+---
+
+# Official Docker images
+
+Castopod pushes 3 Docker images to the Docker Hub during its automated build
+process:
+
+- [**`castopod/castopod`**](https://hub.docker.com/r/castopod/castopod): an all
+  in one castopod image using nginx unit
+- [**`castopod/app`**](https://hub.docker.com/r/castopod/app): the app bundle
+  with all of Castopod dependencies
+- [**`castopod/web-server`**](https://hub.docker.com/r/castopod/web-server): an
+  Nginx configuration for Castopod
+
+Additionally, Castopod requires a MySQL-compatible database. A Redis database
+can be added as a cache handler.
+
+## Supported tags
+
+- `develop` [unstable], latest development branch build
+- `beta` [stable], latest beta version build
+- `latest` [stable], latest version build
+- `1.x.x` [stable], specific version build (since `1.0.0`)
+
+## Example usage
+
+1.  Install [docker](https://docs.docker.com/get-docker/) and
+    [docker-compose](https://docs.docker.com/compose/install/)
+2.  Create a `docker-compose.yml` file with the following:
+
+    ```yml
+    version: "3.7"
+
+    services:
+      app:
+        image: castopod/castopod:latest
+        container_name: "castopod-app"
+        volumes:
+          - castopod-media:/var/www/castopod/public/media
+        environment:
+          MYSQL_DATABASE: castopod
+          MYSQL_USER: castopod
+          MYSQL_PASSWORD: changeme
+          CP_BASEURL: "https://castopod.example.com"
+          CP_ANALYTICS_SALT: changeme
+          CP_CACHE_HANDLER: redis
+          CP_REDIS_HOST: redis
+          CP_REDIS_PASSWORD: changeme
+        networks:
+          - castopod-app
+          - castopod-db
+        ports:
+          - 8000:8000
+        restart: unless-stopped
+
+      mariadb:
+        image: mariadb:10.5
+        container_name: "castopod-mariadb"
+        networks:
+          - castopod-db
+        volumes:
+          - castopod-db:/var/lib/mysql
+        environment:
+          MYSQL_ROOT_PASSWORD: changeme
+          MYSQL_DATABASE: castopod
+          MYSQL_USER: castopod
+          MYSQL_PASSWORD: changeme
+        restart: unless-stopped
+
+      redis:
+        image: redis:7.0-alpine
+        container_name: "castopod-redis"
+        command: --requirepass changeme
+        volumes:
+          - castopod-cache:/data
+        networks:
+          - castopod-app
+
+    volumes:
+      castopod-media:
+      castopod-db:
+      castopod-cache:
+
+    networks:
+      castopod-app:
+      castopod-db:
+    ```
+
+    You have to adapt some variables to your needs (e.g. `CP_BASEURL`,
+    `MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD` and `CP_ANALYTICS_SALT`).
+
+3.  Setup a reverse proxy for TLS (SSL/HTTPS)
+
+    TLS is mandatory for ActivityPub to work. This job can easily be handled by
+    a reverse proxy, for example with [Caddy](https://caddyserver.com/):
+
+    ```
+    #castopod
+    castopod.example.com {
+        reverse_proxy localhost:8000
+    }
+    ```
+
+4.  Run `docker-compose up -d`, wait for it to initialize and head on to
+    `https://castopod.example.com/cp-install` to finish setting up Castopod!
+
+5.  You're all set, start podcasting! 🎙️🚀
+
+## Environment Variables
+
+- **castopod/castopod** and **castopod/app**
+
+  | Variable name                         | Type (`default`)        | Default          |
+  | ------------------------------------- | ----------------------- | ---------------- |
+  | **`CP_BASEURL`**                      | string                  | `undefined`      |
+  | **`CP_MEDIA_BASEURL`**                | ?string                 | `CP_BASEURL`     |
+  | **`CP_ADMIN_GATEWAY`**                | ?string                 | `"cp-admin"`     |
+  | **`CP_AUTH_GATEWAY`**                 | ?string                 | `"cp-auth"`      |
+  | **`CP_ANALYTICS_SALT`**               | string                  | `undefined`      |
+  | **`CP_DATABASE_HOSTNAME`**            | ?string                 | `"mariadb"`      |
+  | **`CP_DATABASE_NAME`**                | ?string                 | `MYSQL_DATABASE` |
+  | **`CP_DATABASE_USERNAME`**            | ?string                 | `MYSQL_USER`     |
+  | **`CP_DATABASE_PASSWORD`**            | ?string                 | `MYSQL_PASSWORD` |
+  | **`CP_DATABASE_PREFIX`**              | ?string                 | `"cp_"`          |
+  | **`CP_CACHE_HANDLER`**                | [`"file"` or `"redis"`] | `"file"`         |
+  | **`CP_REDIS_HOST`**                   | ?string                 | `"localhost"`    |
+  | **`CP_REDIS_PASSWORD`**               | ?string                 | `null`           |
+  | **`CP_REDIS_PORT`**                   | ?number                 | `6379`           |
+  | **`CP_REDIS_DATABASE`**               | ?number                 | `0`              |
+  | **`CP_EMAIL_SMTP_HOST`**              | ?string                 | `undefined`      |
+  | **`CP_EMAIL_FROM`**                   | ?string                 | `undefined`      |
+  | **`CP_EMAIL_SMTP_USERNAME`**          | ?string                 | `"localhost"`    |
+  | **`CP_EMAIL_SMTP_PASSWORD`**          | ?string                 | `null`           |
+  | **`CP_EMAIL_SMTP_PORT`**              | ?number                 | `25`             |
+  | **`CP_EMAIL_SMTP_CRYPTO`**            | [`"tls"` or `"ssl"`]    | `"tls"`          |
+  | **`CP_ENABLE_2FA`**                   | ?boolean                | `undefined`      |
+  | **`CP_MEDIA_FILE_MANAGER`**           | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_ENDPOINT`**            | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_KEY`**                 | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_SECRET`**              | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_REGION`**              | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_BUCKET`**              | ?string                 | `undefined`      |
+  | **`CP_MEDIA_S3_PROTOCOL`**            | ?number                 | `undefined`      |
+  | **`CP_MEDIA_S3_PATH_STYLE_ENDPOINT`** | ?boolean                | `undefined`      |
+  | **`CP_MEDIA_S3_KEY_PREFIX`**          | ?string                 | `undefined`      |
+  | **`CP_DISABLE_HTTPS`**                | ?[`0` or `1`]           | `undefined`      |
+  | **`CP_MAX_BODY_SIZE`**                | ?number (with suffix)   | `512M`           |
+  | **`CP_PHP_MEMORY_LIMIT`**             | ?number (with suffix)   | `512M`           |
+  | **`CP_TIMEOUT`**                      | ?number                 | `900`            |
+
+- **castopod/web-server**
+
+  | Variable name          | Type                  | Default |
+  | ---------------------- | --------------------- | ------- |
+  | **`CP_APP_HOSTNAME`**  | ?string               | `"app"` |
+  | **`CP_MAX_BODY_SIZE`** | ?number (with suffix) | `512M`  |
+  | **`CP_TIMEOUT`**       | ?number               | `900`   |
diff --git a/docs/src/zh-Hant/getting-started/install.md b/docs/src/zh-Hant/getting-started/install.md
new file mode 100644
index 00000000..cdea18ec
--- /dev/null
+++ b/docs/src/zh-Hant/getting-started/install.md
@@ -0,0 +1,238 @@
+---
+title: Installation
+sidebarDepth: 3
+---
+
+# How to install Castopod?
+
+Castopod was thought-out to be easy to install. Whether using dedicated or
+shared hosting, you can install it on most PHP-MySQL compatible web servers.
+
+::: tip Note
+
+We've released official Docker images for Castopod!
+
+If you prefer using Docker, you may skip this and go straight to the
+[docker documentation](./docker.md) for Castopod.
+
+:::
+
+## Requirements
+
+- PHP v8.1 or higher
+- MySQL version 5.7 or higher or MariaDB version 10.2 or higher
+- HTTPS support
+- An [ntp-synced clock](https://wiki.debian.org/NTP) to validate federation's
+  incoming requests
+
+### PHP v8.1 or higher
+
+PHP version 8.1 or higher is required, with the following extensions installed:
+
+- [intl](https://php.net/manual/en/intl.requirements.php)
+- [libcurl](https://php.net/manual/en/curl.requirements.php)
+- [mbstring](https://php.net/manual/en/mbstring.installation.php)
+- [gd](https://www.php.net/manual/en/image.installation.php) with **JPEG**,
+  **PNG** and **WEBP** libraries.
+- [exif](https://www.php.net/manual/en/exif.installation.php)
+
+Additionally, make sure that the following extensions are enabled in your PHP:
+
+- json (enabled by default - don't turn it off)
+- xml (enabled by default - don't turn it off)
+- [mysqlnd](https://php.net/manual/en/mysqlnd.install.php)
+
+### MySQL compatible database
+
+> We recommend using [MariaDB](https://mariadb.org).
+
+::: warning Warning
+
+Castopod only works with supported MySQL 5.7 or higher compatible databases. It
+will break with the previous MySQL v5.6 for example as its end of life was on
+February 5, 2021.
+
+:::
+
+You will need the server hostname, database name, username and password to
+complete the installation process. If you do not have these, please contact your
+server administrator.
+
+#### Privileges
+
+User must have at least these privileges on the database for Castopod to work:
+`CREATE`, `ALTER`, `DELETE`, `EXECUTE`, `INDEX`, `INSERT`, `SELECT`, `UPDATE`,
+`REFERENCES`, `CREATE VIEW`.
+
+### (Optional) FFmpeg v4.1.8 or higher for Video Clips
+
+[FFmpeg](https://www.ffmpeg.org/) version 4.1.8 or higher is required if you
+want to generate Video Clips. The following extensions must be installed:
+
+- **FreeType 2** library for
+  [gd](https://www.php.net/manual/en/image.installation.php).
+
+### (Optional) Other recommendations
+
+- Redis for better cache performances.
+- CDN for static files caching and better performances.
+- e-mail gateway for lost passwords.
+
+## Install instructions
+
+### Pre-requisites
+
+0. Get a Web Server with [requirements](#requirements) installed
+1. Create a MySQL database for Castopod with a user having access and
+   modification privileges (for more info, see
+   [MySQL compatible database](#mysql-compatible-database)).
+2. Activate HTTPS on your domain with an _SSL certificate_.
+3. Download and unzip the latest [Castopod Package](https://castopod.org/) onto
+   the web server if you haven’t already.
+   - ⚠️ Set the web server document root to the `public/` sub-folder within the
+     `castopod` folder.
+4. Add **cron tasks** on your web server for various background processes
+   (replace the paths accordingly):
+
+   ```bash
+      * * * * * /path/to/php /path/to/castopod/spark tasks:run >> /dev/null 2>&1
+   ```
+
+   **Note** - If you do not add this cron task, the following Castopod features
+   will not work:
+
+   - Importing a podcast from an existing RSS feed
+   - Broadcasting social activities to your followers in the fediverse
+   - Broadcasting episodes to open hubs using
+     [WebSub](https://en.wikipedia.org/wiki/WebSub)
+   - Generating video clips -
+     [requires FFmpeg](#optional-ffmpeg-v418-or-higher-for-video-clips)
+
+### (recommended) Install Wizard
+
+1. Run the Castopod install script by going to the install wizard page
+   (`https://your_domain_name.com/cp-install`) in your favorite web browser.
+2. Follow the instructions on your screen.
+3. Start podcasting!
+
+::: info Note
+
+The install script writes a `.env` file in the package root. If you cannot go
+through the install wizard, you can create and edit the `.env` file manually
+based on the `.env.example` file.
+
+:::
+
+### Using CLI
+
+1. Create a `.env` file in the package root based on the `.env.example` file.
+2. Initialize the database using:
+
+   ```sh
+   php spark install:init-database
+   ```
+
+3. Create the superadmin user using:
+
+   ```sh
+   php spark install:create-superadmin
+   ```
+
+4. Head on to your admin gateway to start podcasting!
+
+### Email/SMTP setup
+
+Email configuration is required for some features to work properly (eg.
+retrieving your forgotten password, sending instructions to premium subscribers,
+…)
+
+You may add your email configuration in your instance's `.env` like so:
+
+```ini
+# […]
+
+email.fromEmail="your_email_address"
+email.SMTPHost="your_smtp_host"
+email.SMTPUser="your_smtp_user"
+email.SMTPPass="your_smtp_password"
+```
+
+#### Email config options
+
+| Variable name    | Type                 | Default      |
+| ---------------- | -------------------- | ------------ |
+| **`fromEmail`**  | string               | `undefined`  |
+| **`fromName`**   | string               | `"Castopod"` |
+| **`SMTPHost`**   | string               | `undefined`  |
+| **`SMTPUser`**   | string               | `undefined`  |
+| **`SMTPPass`**   | string               | `undefined`  |
+| **`SMTPPort`**   | number               | `25`         |
+| **`SMTPCrypto`** | [`"tls"` or `"ssl"`] | `"tls"`      |
+
+### Media storage
+
+By default, files are saved to the `public/media` folder using the file system.
+If you need to relocate the `media` folder to a different location, you can
+specify it in your `.env` file as shown below:
+
+```ini
+# […]
+
+media.root="media"
+media.storage="/mnt/storage"
+```
+
+In this example, the files will be saved to the /mnt/storage/media folder. Make
+sure to also update your web server configuration to reflect this change.
+
+### S3
+
+If you prefer storing your media files on an S3 compatible storage, you may
+specify it in your `.env`:
+
+```ini
+# […]
+
+media.fileManager="s3"
+media.s3.endpoint="your_s3_host"
+media.s3.key="your_s3_key"
+media.s3.secret="your_s3_secret"
+media.s3.region="your_s3_region"
+```
+
+#### S3 config options
+
+| Variable name           | Type    | Default     |
+| ----------------------- | ------- | ----------- |
+| **`endpoint`**          | string  | `undefined` |
+| **`key`**               | string  | `undefined` |
+| **`secret`**            | string  | `undefined` |
+| **`region`**            | string  | `undefined` |
+| **`bucket`**            | string  | `castopod`  |
+| **`protocol`**          | number  | `undefined` |
+| **`pathStyleEndpoint`** | boolean | `false`     |
+| **`keyPrefix`**         | string  | `undefined` |
+
+## Community packages
+
+If you don't want to bother with installing Castopod manually, you may use one
+of the packages created and maintained by the open-source community.
+
+### Install with YunoHost
+
+[YunoHost](https://yunohost.org/) is a distribution based on Debian GNU/Linux
+made up of free and open-source software packages. It manages the hardships of
+self-hosting for you.
+
+<div class="flex flex-wrap items-center gap-4">
+
+<a href="https://install-app.yunohost.org/?app=castopod" target="_blank" rel="noopener noreferrer">
+   <img src="https://install-app.yunohost.org/install-with-yunohost.svg" alt="Install Castopod with YunoHost" class="align-middle" />
+</a>
+
+<a href="https://github.com/YunoHost-Apps/castopod_ynh" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-4 py-[.3rem] mx-auto font-semibold text-center text-black rounded-md gap-x-1 border-2 border-solid border-[#333] hover:no-underline hover:bg-gray-100"><svg
+   xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1em" height="1em"
+   class="text-xl"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 2A10 10 0 0 0 2 12a10 10 0 0 0 6.84 9.49c.5.09.69-.21.69-.48l-.02-1.86c-2.51.46-3.16-.61-3.36-1.18-.11-.28-.6-1.17-1.02-1.4-.35-.2-.85-.66-.02-.67.79-.01 1.35.72 1.54 1.02.9 1.52 2.34 1.1 2.91.83a2.1 2.1 0 0 1 .64-1.34c-2.22-.25-4.55-1.11-4.55-4.94A3.9 3.9 0 0 1 6.68 8.8a3.6 3.6 0 0 1 .1-2.65s.83-.27 2.75 1.02a9.28 9.28 0 0 1 2.5-.34c.85 0 1.7.12 2.5.34 1.9-1.3 2.75-1.02 2.75-1.02.54 1.37.2 2.4.1 2.65.63.7 1.02 1.58 1.02 2.68 0 3.84-2.34 4.7-4.56 4.94.36.31.67.91.67 1.85l-.01 2.75c0 .26.19.58.69.48A10.02 10.02 0 0 0 22 12 10 10 0 0 0 12 2z"/></svg>Github
+Repo</a>
+
+</div>
diff --git a/docs/src/zh-Hant/getting-started/security.md b/docs/src/zh-Hant/getting-started/security.md
new file mode 100644
index 00000000..e205698d
--- /dev/null
+++ b/docs/src/zh-Hant/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/zh-Hant/getting-started/update.md b/docs/src/zh-Hant/getting-started/update.md
new file mode 100644
index 00000000..98e019fb
--- /dev/null
+++ b/docs/src/zh-Hant/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/zh-Hant/index.md b/docs/src/zh-Hant/index.md
new file mode 100644
index 00000000..b63ff645
--- /dev/null
+++ b/docs/src/zh-Hant/index.md
@@ -0,0 +1,300 @@
+---
+sidebarDepth: 2
+---
+
+# Welcome 👋
+
+[![release-badge]][release]&nbsp;[![license-badge]][license]&nbsp;[![contributions-badge]][contributions]&nbsp;[![semantic-release-badge]][semantic-release]&nbsp;[![crowdin-badge]][crowdin]&nbsp;[![discord-badge]][discord]&nbsp;[![stars-badge]][stars]
+
+Castopod is a free & open-source hosting platform made for podcasters who want
+engage and interact with their audience.
+
+Castopod is easy to install and was built on top of
+[CodeIgniter4](https://codeigniter.com/), a powerful PHP framework with a very
+small footprint.
+
+<div class="flex items-center">
+  <a href="/getting-started/install" class="inline-flex items-center px-4 py-2 mx-auto font-semibold text-center text-white rounded-full shadow gap-x-1 bg-pine-500 hover:no-underline hover:bg-pine-600">Install<svg viewBox="0 0 24 24" width="1em" height="1em" class="text-xl text-pine-200"><path fill="currentColor" d="m16.172 11-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z"></path></svg></a>
+</div>
+
+## Features
+
+- 🌱 &nbsp;Free & open-source (AGPL v3 License)
+- 🔐 &nbsp;Focused on data sovereignty: your content, audience, and analytics
+  belong to you, and&nbsp;you&nbsp;only
+- 🪄 &nbsp;Podcasting 2.0 features: GUID, locked, transcripts, funding,
+  chapters, location, persons, soundbites, …
+- 💬 &nbsp;Built-in social network:
+  - 🚀 &nbsp;Castopod is part of the Fediverse, a decentralized social network
+  - ❤️ &nbsp;Create posts, share, favourite, and comment on episodes
+- 📈 &nbsp;Built-in analytics:
+  - ⚖️ &nbsp;GDPR / CCPA / LGPD compliant
+  - 🪙 &nbsp;Standard IABv2 audience measurement
+  - 🏡 &nbsp;On-premises analytics, no third party involved
+- 📢 &nbsp;Built-in marketing tools:
+  - ✅ &nbsp;SEO ready (open-graph meta-tags, JSON-LD, …)
+  - 📱 &nbsp;PWA: install as a standalone app
+  - 🎨 &nbsp;Customizable theme colors
+  - 🎬 &nbsp;Generate ready-to-share Video clips from episodes
+  - 🔉 &nbsp;Generate soundbites
+  - ▶️ &nbsp;Embeddable player, embed your episodes on any website
+- 💸 &nbsp;Monetization:
+  - 🔗 &nbsp;Funding links
+  - 📲 &nbsp;listen-to-click ads
+  - 🤝 &nbsp;value4value / WebMonetization
+  - 💎 &nbsp;Premium podcasts
+- 📡 &nbsp;Publish your episodes everywhere with RSS:
+  - 📱 &nbsp;On all indexes and apps: Podcast Index, Apple Podcasts, Spotify,
+    Google Podcasts, Deezer, Podcast Addict, Podfriend, …
+  - ⚡ &nbsp;Broadcast your episodes instantly with WebSub
+- 📥 &nbsp;Podcast import: move your existing podcast into Castopod
+- 📤 &nbsp;Move your podcast out of Castopod
+- 🔀 &nbsp;Multi-tenant: host as many podcasts as you want
+- 👥 &nbsp;Multi-user: add contributors and set roles
+- 🌎 &nbsp;i18n support: translated in English, French, Polish, German,
+  Brazilian Portuguese & Spanish… with
+  [more to come](https://translate.castopod.org)!
+
+## Motivation
+
+The podcasting ecosystem is decentralized by nature: you can create your podcast
+as an RSS file, publish it on the web and have it shared everywhere online.
+
+It is in fact one of the only media to have stayed this way for a long time.
+
+As usages are evolving, more and more people are getting into podcasts: whether
+it is creators finding new ways to share their ideas, or listeners in the search
+for better content.
+
+With podcasting becoming more widely used, some companies are trying to shift it
+towards a more controlled and centralized medium.
+
+Castopod was created in an effort to provide an open and sustainable alternative
+to hosting your podcasts, promoting decentralization to ensure that podcasters
+creativity can express itself.
+
+This project is pushed by the open-source community, and specifically by the
+[Fediverse](https://fediverse.party/en/fediverse/) and
+[Podcasting 2.0](https://podcastindex.org/) movements.
+
+## Comparison with other solutions
+
+We believe that a solution is not necessarily right for everyone, it highly
+depends on your needs. So, here are comparisons with other tools to help you to
+gauge whether Castopod is the right fit for&nbsp;you.
+
+### Castopod vs Wordpress
+
+Castopod is often referred to as "the Wordpress for podcasts" because of the
+similarities between the two. In some ways this is true. And actually, Castopod
+was greatly inspired by the Wordpress ecosystem, seeing the ease of adoption
+from the community and the number of websites running&nbsp;it.
+
+Just like Wordpress, Castopod is free & open source, built using PHP with a
+MySQL database and is packaged in a way that you can easily install on most web
+servers.
+
+Wordpress is a great way to create your website and extend it with plugins to
+get what you want. It is a full fledged CMS that helps you get any type of
+website online.
+
+On the other hand, Castopod is meant to address the podcasters needs
+specifically, focusing on podcasting, and nothing else. You don't need any
+plugin to get you started on your podcasting&nbsp;journey.
+
+This allows optimizing the processes specific to podcasting: ranging from the
+creation of your podcasts and the publication of new episodes all the way to
+broadcasting, marketing and analytics.
+
+Finally, depending on your needs, Wordpress and Castopod can even live side by
+side as they share the same requirements!
+
+### Castopod vs Funkwhale
+
+Funkwhale is a self-hosted, modern free and open-source music server. Just as
+Castopod, Funkwhale is on the fediverse, a decentralized social network allowing
+interoperability between the two.
+
+Funkwhale was initially built around music. And later on, as the project
+evolved, the ability to host podcasts was introduced.
+
+Unlike Funkwhale, Castopod has been designed and built around podcasting
+exclusively. This allows easier implementation for features related to the
+podcasting ecosystem, such as the podcasting 2.0 features (transcripts,
+chapters, locations, persons, …).
+
+So, you should probably use Funkwhale if you want to host your music, and use
+Castopod if you want to host your podcasts.
+
+### Castopod vs other podcast hosts
+
+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!
+
+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:
+
+- Castopod can be self-hosted and is the only solution that allows you to keep
+  full control over what you produce. Also, as it is open-source, you can even
+  customize it as you wish.
+
+- Castopod is the only solution that currently integrates both a decentralized
+  social network with ActivityPub as well as many of the podcasting 2.0
+  features, hoping to bridge the gap between the two.
+
+## Contributing
+
+Love Castopod and would like to help? Take a look at the following documentation
+to get you&nbsp;started.
+
+### Code of conduct
+
+Castopod has adopted a Code of Conduct that we expect project participants to
+adhere to. Please read the
+[CODE_OF_CONDUCT manual](https://code.castopod.org/adaures/castopod/-/blob/beta/CODE_OF_CONDUCT.md)
+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
+development process, how to propose bugfixes and improvements, and how to build
+and test your changes to Castopod.
+
+## Contributors ✨
+
+Thanks goes to these wonderful people
+([emoji key](https://allcontributors.org/docs/en/emoji-key)):
+
+<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
+<!-- prettier-ignore-start -->
+<!-- markdownlint-disable -->
+<table>
+  <tbody>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/yassinedoghri"><img src="https://code.castopod.org/uploads/-/system/user/avatar/3/avatar.png?s=100" width="100px;" alt="Yassine Doghri"/><br /><sub><b>Yassine Doghri</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/issues?author_username=yassinedoghri" title="Bug reports">🐛</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Documentation">📖</a> <a href="https://code.castopod.org/adaures/castopod/merge_requests?scope=all&state=all&approver_usernames[]=yassinedoghri" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-yassinedoghri" title="Maintenance">🚧</a> <a href="#content-yassinedoghri" title="Content">🖋</a> <a href="#design-yassinedoghri" title="Design">🎨</a> <a href="#a11y-yassinedoghri" title="Accessibility">️️️️♿️</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#question-yassinedoghri" title="Answering Questions">💬</a> <a href="#mentoring-yassinedoghri" title="Mentoring">🧑‍🏫</a> <a href="#infra-yassinedoghri" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-yassinedoghri" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-yassinedoghri" title="Project Management">📆</a> <a href="https://blog.castopod.org/author/yassinedoghri/" title="Blogposts">📝</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/benjamin"><img src="https://code.castopod.org/uploads/-/system/user/avatar/2/avatar.png?s=100" width="100px;" alt="Benjamin Bellamy"/><br /><sub><b>Benjamin Bellamy</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/issues?author_username=benjamin" title="Bug reports">🐛</a> <a href="https://code.castopod.org/adaures/castopod/merge_requests?scope=all&state=all&approver_usernames[]=benjamin" title="Reviewed Pull Requests">👀</a> <a href="#content-benjamin" title="Content">🖋</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#question-benjamin" title="Answering Questions">💬</a> <a href="#infra-benjamin" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-benjamin" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://blog.castopod.org/author/benjamin-bellamy/" title="Blogposts">📝</a> <a href="#projectManagement-benjamin" title="Project Management">📆</a> <a href="#talk-benjamin" title="Talks">📢</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/ola-hn"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Ola Hneini"/><br /><sub><b>Ola Hneini</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/merge_requests?scope=all&state=all&approver_usernames[]=ola" title="Reviewed Pull Requests">👀</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Documentation">📖</a> <a href="#maintenance-ola" title="Maintenance">🚧</a> <a href="#question-ola" title="Answering Questions">💬</a> <a href="#ideas-ola" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://mamot.fr/@rdelaage"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Romain de Laage"/><br /><sub><b>Romain de Laage</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="#infra-rdelaage" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Documentation">📖</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#ideas-rdelaage" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/lyonelbernard"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Lyonel Bernard"/><br /><sub><b>Lyonel Bernard</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=Lyonel" title="Bug reports">🐛</a> <a href="#question-Lyonel" title="Answering Questions">💬</a> <a href="#audio-Lyonel" title="Audio">🔊</a> <a href="#ideas-Lyonel" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://www.crypticchameleon.com/"><img src="https://secure.gravatar.com/avatar/7c2a721b52d0763673a600e8f01bd745?s=80&d=identicon?s=100" width="100px;" alt="Christopher Lagonick-Weitzel"/><br /><sub><b>Christopher Lagonick-Weitzel</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=ctlw83" title="Bug reports">🐛</a> <a href="#question-ctlw83" title="Answering Questions">💬</a> <a href="#audio-ctlw83" title="Audio">🔊</a> <a href="#ideas-ctlw83" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://ernestoacosta.me/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Ernesto Acosta"/><br /><sub><b>Ernesto Acosta</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=ernestoacostame" title="Bug reports">🐛</a> <a href="#audio-ernestoacostame" title="Audio">🔊</a> <a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#question-ernestoacostame" title="Answering Questions">💬</a> <a href="#ideas-ernestoacostame" title="Ideas, Planning, & Feedback">🤔</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://mastodon.fedi.bzh/@ewen"><img src="https://mastodon.fedi.bzh/system/accounts/avatars/000/000/002/original/6f387690a504ae46.jpg?s=100" width="100px;" alt="Ewen"/><br /><sub><b>Ewen</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#ideas-3wen" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/Behel"><img src="https://secure.gravatar.com/avatar/ad63ee8ef8e3db8253d21e5012d2724f?s=80&d=identicon?s=100" width="100px;" alt="Bastien Luneteau"/><br /><sub><b>Bastien Luneteau</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a> <a href="https://code.castopod.org/adaures/castopod/issues?author_username=Behel" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://www.cecillie.fr/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Cécile Ricordeau"/><br /><sub><b>Cécile Ricordeau</b></sub></a><br /><a href="#design-cecillie" title="Design">🎨</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/PatrykMis"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Patryk Miś"/><br /><sub><b>Patryk Miś</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/mspanc"><img src="https://secure.gravatar.com/avatar/eed8337939641eac5ad0b570bd6acf96?s=80&d=identicon?s=100" width="100px;" alt="Marcin Lewandowski"/><br /><sub><b>Marcin Lewandowski</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=mspanc" title="Bug reports">🐛</a> <a href="#ideas-mspanc" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/SJanik"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Sebastian Janik"/><br /><sub><b>Sebastian Janik</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/patryk"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Patryk Karczmarczyk"/><br /><sub><b>Patryk Karczmarczyk</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/ddenis"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="denis d"/><br /><sub><b>denis d</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=ddenis" title="Bug reports">🐛</a> <a href="#ideas-ddenis" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/douglaskastle"><img src="https://secure.gravatar.com/avatar/b7e652ba4b6bcd440afa069e7f7bc9e6?s=80&d=identicon?s=100" width="100px;" alt="Douglas Kastle"/><br /><sub><b>Douglas Kastle</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=douglaskastle" title="Bug reports">🐛</a> <a href="#ideas-douglaskastle" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/cExplorer"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="cExplorer"/><br /><sub><b>cExplorer</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=cExplorer" title="Bug reports">🐛</a> <a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/imacrea"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="ImaCrea"/><br /><sub><b>ImaCrea</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=imacrea" title="Bug reports">🐛</a> <a href="#ideas-imacrea" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/jonas"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Jonas S"/><br /><sub><b>Jonas S</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/yannL"><img src="https://secure.gravatar.com/avatar/9c46600ce566ec6d526370d8e104b1c8?s=80&d=identicon?s=100" width="100px;" alt="LEFEBVRE Yann"/><br /><sub><b>LEFEBVRE Yann</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=yannL" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/spaetz"><img src="https://secure.gravatar.com/avatar/278e1af65e82993efd0ba7bbbacf6435?s=80&d=identicon?s=100" width="100px;" alt="Sebastian Späth"/><br /><sub><b>Sebastian Späth</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=spaetz" title="Bug reports">🐛</a> <a href="#ideas-spaetz" title="Ideas, Planning, & Feedback">🤔</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/rocky"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="rocky III"/><br /><sub><b>rocky III</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=rocky" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/Regenpfeifer"><img src="https://code.castopod.org/uploads/-/system/user/avatar/103/avatar.png?s=100" width="100px;" alt="Hermann Josef Eckl"/><br /><sub><b>Hermann Josef Eckl</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=Regenpfeifer" title="Bug reports">🐛</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/cyrilledel"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Delhaye Cyrille"/><br /><sub><b>Delhaye Cyrille</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=cyrilledel" title="Bug reports">🐛</a> <a href="#ideas-cyrilledel" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/otetranome"><img src="https://code.castopod.org/uploads/-/system/user/avatar/113/avatar.png?s=100" width="100px;" alt="João Leandro"/><br /><sub><b>João Leandro</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a> <a href="#ideas-otetranome" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://achouvardas.eu/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Angelos Chouvardas"/><br /><sub><b>Angelos Chouvardas</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://mastodon.fjerland.no/@eivind"><img src="https://mastodon.fjerland.no/system/accounts/avatars/107/769/768/295/192/222/original/e5c985fea6487dcb.jpg?s=100" width="100px;" alt="Eivind"/><br /><sub><b>Eivind</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/forght"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15073833/large/82d1e2e443a6df7edc43a7405dfeeb75_default.png?s=100" width="100px;" alt="forght"/><br /><sub><b>forght</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/glottis0q"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15209934/large/8b17ef6a7399f0b82a8198f87c224195.png?s=100" width="100px;" alt="glottis0q"/><br /><sub><b>glottis0q</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://mstdn.fr/@ButterflyOfFire"><img src="https://static.mstdn.fr/static/accounts/avatars/000/065/901/original/5908e93ad5447f15.png?s=100" width="100px;" alt="ButterflyOfFire"/><br /><sub><b>ButterflyOfFire</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/lil5"><img src="https://avatars.githubusercontent.com/u/17646836?v=4?s=100" width="100px;" alt="Lucian I. Last"/><br /><sub><b>Lucian I. Last</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/luuzviir"><img src="https://crowdin-static.downloads.crowdin.com/avatar/13166188/large/d03ab0abc7ce354b210d836955cd3805_default.png?s=100" width="100px;" alt="LuuzViir"/><br /><sub><b>LuuzViir</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/cthtc"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15211502/large/ed0651060cb8474a9519b5168bd377c1_default.png?s=100" width="100px;" alt="CTHTC"/><br /><sub><b>CTHTC</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/retrograde"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15021651/large/b10c4057f85bf4de49c7fdf01354ecde.jpeg?s=100" width="100px;" alt="Russian Retro"/><br /><sub><b>Russian Retro</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/mareklach"><img src="https://crowdin-static.downloads.crowdin.com/avatar/13572324/large/3eeba8d569c247ace33862bf4ef4748f.jpeg?s=100" width="100px;" alt="Marek L'ach"/><br /><sub><b>Marek L'ach</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/gunchleoc"><img src="https://crowdin-static.downloads.crowdin.com/avatar/13043878/large/3223f7b606296a8b1c92c5de39c459a2_default.png?s=100" width="100px;" alt="GunChleoc"/><br /><sub><b>GunChleoc</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/gabisnow"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15214858/large/5b083bdf9c9e9de67cc6ee72a6c8db18_default.png?s=100" width="100px;" alt="GabiSnow"/><br /><sub><b>GabiSnow</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/bendaha"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15331656/large/cd92450d2c20202299fb3a0075903e20_default.png?s=100" width="100px;" alt="bendaha"/><br /><sub><b>bendaha</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/samuelroland"><img src="https://crowdin-static.downloads.crowdin.com/avatar/14980053/large/3e154a37d03d6e98ae402ed3f930f4f5.png?s=100" width="100px;" alt="Samuel Roland"/><br /><sub><b>Samuel Roland</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://dimitriregnier.net/"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Dimitri Regnier"/><br /><sub><b>Dimitri Regnier</b></sub></a><br /><a href="#ideas-dimregnier" title="Ideas, Planning, & Feedback">🤔</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://im.irithys.com/@thy"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15405614/large/3086461c47cce0a0c031925e5f943412.png?s=100" width="100px;" alt="irithys"/><br /><sub><b>irithys</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/caos30"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Sergi"/><br /><sub><b>Sergi</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/xosem"><img src="https://crowdin-static.downloads.crowdin.com/avatar/12617257/large/a201650da44fed28890b0e0d8477a663.jpg?s=100" width="100px;" alt="ghose (XoseM)"/><br /><sub><b>ghose (XoseM)</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/basen1982"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="Andreas Olsson"/><br /><sub><b>Andreas Olsson</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/leonfrom"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="leonfrom"/><br /><sub><b>leonfrom</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/agentcobra57"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="agentcobra"/><br /><sub><b>agentcobra</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/alephoto85"><img src="https://crowdin-static.downloads.crowdin.com/avatar/15094649/large/530391f54157af52ae33058ec15b0f99.jpg?s=100" width="100px;" alt="Alessandro"/><br /><sub><b>Alessandro</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://crowdin.com/profile/liimee"><img src="https://castopod.org/assets/images/castopod-avatar.jpg?s=100" width="100px;" alt="liimee"/><br /><sub><b>liimee</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/ahmedsabouni"><img src="https://avatars.githubusercontent.com/u/74497842?v=4?s=100" width="100px;" alt="Ahmed Sabouni"/><br /><sub><b>Ahmed Sabouni</b></sub></a><br /><a href="https://translate.castopod.org" title="Translation">🌍</a></td>
+    </tr>
+    <tr>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/KrzysztofDomanczyk"><img src="https://avatars.githubusercontent.com/u/75178474?v=4?s=100" width="100px;" alt="KrzysztofDomanczyk"/><br /><sub><b>KrzysztofDomanczyk</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://code.castopod.org/NeoluxConsulting"><img src="https://secure.gravatar.com/avatar/6e745565356330c1e29a85d52bffdaa1?s=80&d=identicon?s=100" width="100px;" alt="Guy Martin"/><br /><sub><b>Guy Martin</b></sub></a><br /><a href="https://code.castopod.org/adaures/castopod/issues?author_username=NeoluxConsulting" title="Bug reports">🐛</a> <a href="https://code.castopod.org/adaures/castopod/commits/master" title="Code">💻</a></td>
+    </tr>
+  </tbody>
+</table>
+
+<!-- markdownlint-restore -->
+<!-- prettier-ignore-end -->
+
+<!-- ALL-CONTRIBUTORS-LIST:END -->
+
+This project follows the
+[all-contributors](https://github.com/all-contributors/all-contributors)
+specification. Contributions of any kind welcome!
+
+## Contact
+
+You may reach us for help or ask any question you have on:
+
+- [Discord](https://castopod.org/discord) (for direct interaction with
+  developers and the community)
+- [Issue tracker](https://code.castopod.org/adaures/castopod/-/issues) (for
+  feature requests & bug reports)
+
+Alternatively, you can follow us on social media platforms to get news about
+Castopod:
+
+- [podlibre.social](https://podlibre.social/@Castopod) (Mastodon instance)
+- [Twitter](https://twitter.com/castopod)
+- [LinkedIn](https://linkedin.com/company/castopod)
+- [Facebook](https://www.facebook.com/castopod)
+
+## Sponsors
+
+The ongoing development of Castopod is made possible with the support of its
+backers. If you'd like to help, please consider
+[sponsoring Castopod's development](https://opencollective.com/castopod/contribute).
+
+<div class="flex flex-wrap gap-x-16 gap-y-8">
+  <a href="https://adaures.com/" target="_blank" rel="noopener noreferrer"><img src="/images/sponsors/adaures.svg" alt="Ad Aures Logo" class="h-16" /></a>
+  <a href="https://nlnet.nl/project/Castopod/" target="_blank" rel="noopener noreferrer"><img src="/images/sponsors/nlnet.svg" alt="NLnet Logo" class="h-16" /></a>
+</div>
+
+## License
+
+[GNU Affero General Public License v3.0](https://choosealicense.com/licenses/agpl-3.0/)
+
+Copyright © 2020-present, [Ad Aures](https://adaures.com/).
+https://img.shields.io/gitlab/v/release/2?color=brightgreen&gitlab_url=https%3A%2F%2Fcode.castopod.org%2F&include_prereleases&label=release
+https://img.shields.io/github/license/ad-aures/castopod?color=blue
+https://img.shields.io/badge/contributions-welcome-brightgreen.svg
+https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
+https://img.shields.io/github/stars/ad-aures/castopod?style=social
+
+[release]: https://code.castopod.org/adaures/castopod/-/releases
+[license]: https://code.castopod.org/adaures/castopod/-/blob/beta/LICENSE.md
+[contributions]: https://code.castopod.org/adaures/castopod/-/issues
+[semantic-release]: https://github.com/semantic-release/semantic-release
+[discord]: https://castopod.org/discord
+[stars]: https://github.com/ad-aures/castopod/stargazers
+[crowdin]: https://translate.castopod.org/project/castopod
diff --git a/modules/Admin/Language/de/Breadcrumb.php b/modules/Admin/Language/de/Breadcrumb.php
index c271fd31..89fc585d 100644
--- a/modules/Admin/Language/de/Breadcrumb.php
+++ b/modules/Admin/Language/de/Breadcrumb.php
@@ -39,11 +39,11 @@ return [
     'my-account' => 'Mein Konto',
     'change-password' => 'Passwort ändern',
     'imports' => 'Importe',
-    'sync-feeds' => 'synchronize feeds',
+    'sync-feeds' => 'Feeds synchronisieren',
     'platforms' => 'Plattformen',
     'social' => 'soziale Netzwerke',
     'funding' => 'Finanzierung',
-    'monetization-other' => 'other monetization',
+    'monetization-other' => 'sonstige Monetarisierung',
     'analytics' => 'Statistiken',
     'locations' => 'Orte',
     'webpages' => 'Webseiten',
diff --git a/modules/Admin/Language/de/Common.php b/modules/Admin/Language/de/Common.php
index c4ff79bf..cc668a33 100644
--- a/modules/Admin/Language/de/Common.php
+++ b/modules/Admin/Language/de/Common.php
@@ -40,7 +40,7 @@ return [
         ],
         'upload_file' => 'Eine Datei hochladen',
         'remote_url' => 'Externe URL',
-        'save' => 'Save',
+        'save' => 'Speichern',
     ],
     'play_episode_button' => [
         'play' => 'Abspielen',
diff --git a/modules/Admin/Language/de/Episode.php b/modules/Admin/Language/de/Episode.php
index fd8f84f3..15009e31 100644
--- a/modules/Admin/Language/de/Episode.php
+++ b/modules/Admin/Language/de/Episode.php
@@ -139,9 +139,9 @@ return [
         'location_name' => 'Standortname oder Adresse',
         'location_name_hint' => 'Dies kann ein realer oder fiktiver Ort sein',
         'transcript' => 'Transkript (Untertitel)',
-        'transcript_hint' => 'Only .srt or .vtt are allowed.',
+        'transcript_hint' => 'Nur .srt oder .vtt sind erlaubt.',
         'transcript_download' => 'Transkript herunterladen',
-        'transcript_file' => 'Transcript file (.srt or .vtt)',
+        'transcript_file' => 'Transkriptdatei (.srt oder .vtt)',
         'transcript_remote_url' => 'Remote-URL für Transkript',
         'transcript_file_delete' => 'Transkriptionsdatei löschen',
         'chapters' => 'Kapitel',
diff --git a/modules/Admin/Language/de/Navigation.php b/modules/Admin/Language/de/Navigation.php
index 752c2186..f7b7b0ba 100644
--- a/modules/Admin/Language/de/Navigation.php
+++ b/modules/Admin/Language/de/Navigation.php
@@ -12,7 +12,7 @@ return [
     'toggle_sidebar' => 'Seitenleiste ein/aus',
     'go_to_website' => 'Gehe zur Webseite',
     'go_to_admin' => 'Gehe zu Admin',
-    'not-authorized' => 'Not authorized',
+    'not-authorized' => 'Nicht berechtigt',
     'dashboard' => 'Übersicht',
     'admin' => 'Startseite',
     'podcasts' => 'Podcasts',
@@ -35,7 +35,7 @@ return [
     'settings' => 'Einstellungen',
     'settings-general' => 'Allgemein',
     'settings-theme' => 'Erscheinungsbild',
-    'admin-about' => 'About',
+    'admin-about' => 'Über',
     'account' => [
         'my-account' => 'Mein Konto',
         'change-password' => 'Passwort ändern',
diff --git a/modules/Admin/Language/de/Platforms.php b/modules/Admin/Language/de/Platforms.php
index 48b5c747..41751316 100644
--- a/modules/Admin/Language/de/Platforms.php
+++ b/modules/Admin/Language/de/Platforms.php
@@ -10,21 +10,21 @@ declare(strict_types=1);
 
 return [
     'title' => [
-        'podcasting' => 'Podcasting platforms',
-        'social' => 'Social networks',
-        'funding' => 'Funding links',
+        'podcasting' => 'Podcast-Plattformen',
+        'social' => 'Soziale Medien',
+        'funding' => 'Finanzierungslinks',
     ],
-    'website' => 'Website',
+    'website' => 'Webseite',
     'home_url' => 'Gehe zu {platformName} Webseite',
-    'register' => 'Register',
+    'register' => 'Registrieren',
     'submit_url' => 'Sende deinen Podcast an {platformName}',
-    'your_link' => 'Your link',
+    'your_link' => 'Dein Link',
     'your_id' => [
-        'podcasting' => 'Your ID',
-        'social' => 'Your ID',
-        'funding' => 'Your CTA',
+        'podcasting' => 'Deine ID',
+        'social' => 'Deine ID',
+        'funding' => 'Deine CTA',
     ],
-    'your_cta' => 'Your call to action',
+    'your_cta' => 'Dein Aufruf zur Aktion',
     'visible' => 'Auf Podcast-Homepage anzeigen?',
     'on_embed' => 'Auf einbettbarem Player anzeigen?',
     'remove' => 'Entferne {platformName}',
diff --git a/modules/Admin/Language/de/Podcast.php b/modules/Admin/Language/de/Podcast.php
index 5cffc366..cc83786e 100644
--- a/modules/Admin/Language/de/Podcast.php
+++ b/modules/Admin/Language/de/Podcast.php
@@ -22,7 +22,7 @@ return [
     'delete' => 'Podcast löschen',
     'see_episodes' => 'Episoden ansehen',
     'see_contributors' => 'Mitwirkende anzeigen',
-    'monetization_other' => 'Other monetization',
+    'monetization_other' => 'Sonstige Monetarisierung',
     'go_to_page' => 'Gehe zur Seite',
     'latest_episodes' => 'Neueste Folgen',
     'see_all_episodes' => 'Alle Folgen anzeigen',
@@ -58,7 +58,7 @@ return [
     'form' => [
         'identity_section_title' => 'Podcast-Identität',
         'identity_section_subtitle' => 'Diese Felder erlauben es dir, Aufmerksamkeit zu bekommen.',
-        'fediverse_section_title' => 'Fediverse identity',
+        'fediverse_section_title' => 'Fediverse-Identität',
 
         'cover' => 'Podcast-Cover',
         'cover_size_hint' => 'Das Cover muss quadratisch und mindestens 1400px breit und hoch sein.',
@@ -74,17 +74,17 @@ return [
             'episodic' => 'Episodisch',
             'episodic_hint' => 'Wenn Folgen ohne bestimmte Reihenfolge abgespielt werden sollen. Neueste Folgen werden zuerst angezeigt.',
             'serial' => 'Seriell',
-            'serial_hint' => 'If episodes are intended to be consumed in sequential order. Episodes will be presented in numeric order.',
+            'serial_hint' => 'Wenn Episoden in sequenzieller Reihenfolge konsumiert werden sollen. Episoden werden in numerischer Reihenfolge angezeigt.',
         ],
         'medium' => [
             'label' => 'Medium',
             'hint' => 'Medium as represented by podcast:medium tag in RSS. Changing this may change how players present your feed.',
             'podcast' => 'Podcast',
-            'podcast_hint' => 'Describes a feed for a podcast show.',
-            'music' => 'Music',
+            'podcast_hint' => 'Beschreibt einen Feed für eine Podcast-Show.',
+            'music' => 'Musik',
             'music_hint' => 'A feed of music organized into an "album" with each item a song within the album.',
-            'audiobook' => 'Audiobook',
-            'audiobook_hint' => 'Specific types of audio with one item per feed, or where items represent chapters within the book.',
+            'audiobook' => 'Hörbuch',
+            'audiobook_hint' => 'Spezifische Arten von Audio mit einem Eintrag pro Feed, oder wenn Elemente Kapitel innerhalb des Buches darstellen.',
         ],
         'description' => 'Beschreibung',
         'classification_section_title' => 'Klassifikation',
@@ -109,8 +109,8 @@ return [
         'owner_email' => 'E-Mail des Eigentümers',
         'owner_email_hint' =>
             'Wird von den meisten Plattformen verwendet werden, um den Podcast-Besitz zu überprüfen. Sichtbar im öffentlichen RSS-Feed.',
-        'is_owner_email_removed_from_feed' => 'Remove the owner email from the public RSS feed',
-        'is_owner_email_removed_from_feed_hint' => 'You may need to temporarily unhide the email so that a directory can verify your podcast ownership.',
+        'is_owner_email_removed_from_feed' => 'Entferne die Eigentümer-E-Mail aus dem öffentlichen RSS-Feed',
+        'is_owner_email_removed_from_feed_hint' => 'Möglicherweise müssen Sie die E-Mail vorübergehend freigeben, damit ein Verzeichnis Ihren Podcast-Besitz verifizieren kann.',
         'publisher' => 'Herausgeber',
         'publisher_hint' =>
             'Die Gruppe, die für die Erstellung des Podcasts verantwortlich ist. Oft bezogen auf die Muttergesellschaft oder das Netzwerk eines Podcasts. Dieses Feld wird manchmal als \'Autor\' bezeichnet.',
@@ -126,7 +126,7 @@ return [
         'premium_by_default' => 'Episoden müssen standardmäßig als Premium festgelegt werden',
         'premium_by_default_hint' => 'Podcast-Episoden werden standardmäßig als Premium markiert. Sie können dennoch einzelne Episoden, Trailer oder Boni als öffentlich festlegen.',
         'op3' => 'Open Podcast Prefix Project (OP3)',
-        'op3_link' => 'Visit your OP3 dashboard (external link)',
+        'op3_link' => 'Besuche dein OP3-Dashboard (externer Link)',
         'op3_hint' => 'Werten Sie Ihre Analysedaten mit OP3 auf, einem quelloffenen und vertrauenswürdigen Analysedienst eines Drittanbieters. Teilen, validieren und vergleichen Sie Ihre Analysedaten in dem offenen Podcast-Ökosystem.',
         'op3_enable' => 'OP3-Analysedienst aktivieren',
         'op3_enable_hint' => 'Aus Sicherheitsgründen werden die Analysedaten von Premium-Episoden nicht mit OP3 geteilt.',
diff --git a/modules/Admin/Language/de/PodcastNavigation.php b/modules/Admin/Language/de/PodcastNavigation.php
index 6512d570..6fa2e17d 100644
--- a/modules/Admin/Language/de/PodcastNavigation.php
+++ b/modules/Admin/Language/de/PodcastNavigation.php
@@ -10,13 +10,13 @@ declare(strict_types=1);
 
 return [
     'go_to_page' => 'Zur Podcast-Seite gehen',
-    'rss_feed' => 'RSS feed',
+    'rss_feed' => 'RSS-Feed',
     'dashboard' => 'Podcast-Dashboard',
     'podcast-view' => 'Startseite',
     'podcast-edit' => 'Podcast bearbeiten',
     'podcast-persons-manage' => 'Mitwirkende verwalten',
     'podcast-imports' => 'Podcast-Importe',
-    'podcast-imports-sync' => 'Sync feeds',
+    'podcast-imports-sync' => 'Feeds synchronisieren',
     'episodes' => 'Folgen',
     'episode-list' => 'Alle Episoden',
     'episode-create' => 'Neue Episoden',
@@ -28,15 +28,15 @@ return [
     'podcast-analytics-players' => 'Podcast-Player',
     'podcast-analytics-listening-time' => 'Hörzeit',
     'podcast-analytics-time-periods' => 'Zeiträume',
-    'monetization' => 'Monetization',
+    'monetization' => 'Monetarisierung',
     'subscription-list' => 'Alle Abonnements',
-    'subscription-create' => 'Add subscription',
+    'subscription-create' => 'Abonnement hinzufügen',
     'contributors' => 'Mitwirkende',
     'contributor-list' => 'Alle Unterstützer',
     'contributor-add' => 'Mitwirkenden hinzufügen',
     'broadcast' => 'Broadcast',
-    'platforms-podcasting' => 'Podcasting apps',
+    'platforms-podcasting' => 'Podcast-Apps',
     'platforms-social' => 'Soziale Netzwerke',
-    'platforms-funding' => 'Funding links',
-    'podcast-monetization-other' => 'Other',
+    'platforms-funding' => 'Finanzierungslinks',
+    'podcast-monetization-other' => 'Andere',
 ];
diff --git a/modules/Admin/Language/de/Validation.php b/modules/Admin/Language/de/Validation.php
index 212cfb73..bae6668c 100644
--- a/modules/Admin/Language/de/Validation.php
+++ b/modules/Admin/Language/de/Validation.php
@@ -13,5 +13,5 @@ return [
         '{field} ist entweder kein Bild, oder es ist nicht breit oder hoch genug.',
     'is_image_ratio' =>
         '{field} ist entweder kein Bild oder nicht das richtige Verhältnis.',
-    'is_json' => '{field} contains invalid JSON.',
+    'is_json' => '{field} enthält ungültiges JSON.',
 ];
diff --git a/modules/Admin/Language/eu/AboutCastopod.php b/modules/Admin/Language/eu/AboutCastopod.php
new file mode 100644
index 00000000..3fb62aff
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Breadcrumb.php b/modules/Admin/Language/eu/Breadcrumb.php
new file mode 100644
index 00000000..6a678d4e
--- /dev/null
+++ b/modules/Admin/Language/eu/Breadcrumb.php
@@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+use Modules\Admin\Config\Admin;
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'label' => 'breadcrumb',
+    config(Admin::class)
+        ->gateway => 'Home',
+    'podcasts' => 'podcasts',
+    'episodes' => 'episodes',
+    'subscriptions' => 'subscriptions',
+    'contributors' => 'contributors',
+    'pages' => 'pages',
+    'settings' => 'settings',
+    'theme' => 'theme',
+    'about' => 'about',
+    'add' => 'add',
+    'new' => 'new',
+    'edit' => 'edit',
+    'persons' => 'persons',
+    'publish' => 'publish',
+    'publish-edit' => 'edit publication',
+    'publish-date-edit' => 'edit publication date',
+    'unpublish' => 'unpublish',
+    'delete' => 'delete',
+    'remove' => 'remove',
+    'fediverse' => 'fediverse',
+    'blocked-actors' => 'blocked actors',
+    'blocked-domains' => 'blocked domains',
+    'users' => 'users',
+    'my-account' => 'my account',
+    'change-password' => 'change password',
+    'imports' => 'imports',
+    'sync-feeds' => 'synchronize feeds',
+    'platforms' => 'platforms',
+    'social' => 'social networks',
+    'funding' => 'funding',
+    'monetization-other' => 'other monetization',
+    'analytics' => 'analytics',
+    'locations' => 'locations',
+    'webpages' => 'web pages',
+    'unique-listeners' => 'unique listeners',
+    'players' => 'players',
+    'listening-time' => 'listening time',
+    'time-periods' => 'time periods',
+    'soundbites' => 'soundbites',
+    'video-clips' => 'video clips',
+    'embed' => 'embeddable player',
+    'notifications' => 'notifications',
+    'suspend' => 'suspend',
+];
diff --git a/modules/Admin/Language/eu/Charts.php b/modules/Admin/Language/eu/Charts.php
new file mode 100644
index 00000000..6ede2510
--- /dev/null
+++ b/modules/Admin/Language/eu/Charts.php
@@ -0,0 +1,41 @@
+<?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 [
+    'by_service_weekly' => 'Episode downloads by service (for the past week)',
+    'by_player_weekly' => 'Episode downloads by player (for the past week)',
+    'by_player_yearly' => 'Episode downloads by player (for the past year)',
+    'by_device_weekly' => 'Episode downloads by device (for the past week)',
+    'by_os_weekly' => 'Episode downloads by O.S. (for the past week)',
+    'podcast_by_region' => 'Episode downloads by region (for the past week)',
+    'unique_daily_listeners' => 'Daily unique listeners',
+    'unique_monthly_listeners' => 'Monthly unique listeners',
+    'by_browser' => 'Web pages usage by browser (for the past week)',
+    'podcast_by_day' => 'Episode daily downloads',
+    'podcast_by_month' => 'Episode monthly downloads',
+    'episode_by_day' => 'Episode daily downloads (first 60 days)',
+    'episode_by_month' => 'Episode monthly downloads',
+    'episodes_by_day' =>
+        '5 latest episodes downloads (during their first 60 days)',
+    'by_country_weekly' => 'Episode downloads by country (for the past week)',
+    'by_country_yearly' => 'Episode downloads by country (for the past year)',
+    'by_domain_weekly' => 'Web pages visits by source (for the past week)',
+    'by_domain_yearly' => 'Web pages visits by source (for the past year)',
+    'by_entry_page' => 'Web pages visits by landing page (for the past week)',
+    'podcast_bots' => 'Bots (crawlers)',
+    'daily_listening_time' => 'Daily cumulative listening time',
+    'monthly_listening_time' => 'Monthly cumulative listening time',
+    'by_weekday' => 'By week day (for the past 60 days)',
+    'by_hour' => 'By time of day (for the past 60 days)',
+    'podcast_by_bandwidth' => 'Daily used bandwidth (in MB)',
+    'total_storage_by_month' => 'Monthly storage (in MB)',
+    'total_bandwidth_by_month' => 'Monthly used bandwidth (in MB)',
+    'total_bandwidth_by_month_limit' => 'Limited to {totalBandwidth} per month',
+];
diff --git a/modules/Admin/Language/eu/Common.php b/modules/Admin/Language/eu/Common.php
new file mode 100644
index 00000000..74addcf2
--- /dev/null
+++ b/modules/Admin/Language/eu/Common.php
@@ -0,0 +1,52 @@
+<?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 [
+    'yes' => 'Yes',
+    'no' => 'No',
+    'cancel' => 'Cancel',
+    'optional' => 'Optional',
+    'more' => 'More',
+    'no_data' => 'No data found!',
+    'close' => 'Close',
+    'edit' => 'Edit',
+    'copy' => 'Copy',
+    'copied' => 'Copied!',
+    'home' => 'Home',
+    'explicit' => 'Explicit',
+    'powered_by' => 'Powered by {castopod}',
+    'actions' => 'Actions',
+    'pageInfo' => 'Page {currentPage} out of {pageCount}',
+    'go_back' => 'Go back',
+    'forms' => [
+        'editor' => [
+            'write' => 'Write',
+            'preview' => 'Preview',
+            'help' => 'Powered by markdown',
+        ],
+        'multiSelect' => [
+            'selectText' => 'Press to select',
+            'loadingText' => 'Loading…',
+            'noResultsText' => 'No results found',
+            'noChoicesText' => 'No choices to choose from',
+            'maxItemText' => 'Cannot add more items',
+        ],
+        'upload_file' => 'Upload a file',
+        'remote_url' => 'Remote URL',
+        'save' => 'Save',
+    ],
+    'play_episode_button' => [
+        'play' => 'Play',
+        'playing' => 'Playing',
+    ],
+    'size_limit' => 'Size limit: {0}.',
+    'choose_interact' => 'Choose how to interact',
+    'view' => 'View',
+];
diff --git a/modules/Admin/Language/eu/Countries.php b/modules/Admin/Language/eu/Countries.php
new file mode 100644
index 00000000..4cd5d9c8
--- /dev/null
+++ b/modules/Admin/Language/eu/Countries.php
@@ -0,0 +1,264 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * ISO 3166 country codes
+ *
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'AD' => 'Andorra',
+    'AE' => 'United Arab Emirates',
+    'AF' => 'Afghanistan',
+    'AG' => 'Antigua and Barbuda',
+    'AI' => 'Anguilla',
+    'AL' => 'Albania',
+    'AM' => 'Armenia',
+    'AO' => 'Angola',
+    'AQ' => 'Antarctica',
+    'AR' => 'Argentina',
+    'AS' => 'American Samoa',
+    'AT' => 'Austria',
+    'AU' => 'Australia',
+    'AW' => 'Aruba',
+    'AX' => 'Åland Islands',
+    'AZ' => 'Azerbaijan',
+    'BA' => 'Bosnia and Herzegovina',
+    'BB' => 'Barbados',
+    'BD' => 'Bangladesh',
+    'BE' => 'Belgium',
+    'BF' => 'Burkina Faso',
+    'BG' => 'Bulgaria',
+    'BH' => 'Bahrain',
+    'BI' => 'Burundi',
+    'BJ' => 'Benin',
+    'BL' => 'Saint Barthélemy',
+    'BM' => 'Bermuda',
+    'BN' => 'Brunei Darussalam',
+    'BO' => 'Bolivia, Plurinational State of',
+    'BQ' => 'Bonaire, Sint Eustatius and Saba',
+    'BR' => 'Brazil',
+    'BS' => 'Bahamas',
+    'BT' => 'Bhutan',
+    'BV' => 'Bouvet Island',
+    'BW' => 'Botswana',
+    'BY' => 'Belarus',
+    'BZ' => 'Belize',
+    'CA' => 'Canada',
+    'CC' => 'Cocos (Keeling) Islands',
+    'CD' => 'Congo, the Democratic Republic of the',
+    'CF' => 'Central African Republic',
+    'CG' => 'Congo',
+    'CH' => 'Switzerland',
+    'CI' => "Côte d'Ivoire",
+    'CK' => 'Cook Islands',
+    'CL' => 'Chile',
+    'CM' => 'Cameroon',
+    'CN' => 'China',
+    'CO' => 'Colombia',
+    'CR' => 'Costa Rica',
+    'CU' => 'Cuba',
+    'CV' => 'Cape Verde',
+    'CW' => 'Curaçao',
+    'CX' => 'Christmas Island',
+    'CY' => 'Cyprus',
+    'CZ' => 'Czech Republic',
+    'DE' => 'Germany',
+    'DJ' => 'Djibouti',
+    'DK' => 'Denmark',
+    'DM' => 'Dominica',
+    'DO' => 'Dominican Republic',
+    'DZ' => 'Algeria',
+    'EC' => 'Ecuador',
+    'EE' => 'Estonia',
+    'EG' => 'Egypt',
+    'EH' => 'Western Sahara',
+    'ER' => 'Eritrea',
+    'ES' => 'Spain',
+    'ET' => 'Ethiopia',
+    'FI' => 'Finland',
+    'FJ' => 'Fiji',
+    'FK' => 'Falkland Islands (Malvinas)',
+    'FM' => 'Micronesia, Federated States of',
+    'FO' => 'Faroe Islands',
+    'FR' => 'France',
+    'GA' => 'Gabon',
+    'GB' => 'United Kingdom',
+    'GD' => 'Grenada',
+    'GE' => 'Georgia',
+    'GF' => 'French Guiana',
+    'GG' => 'Guernsey',
+    'GH' => 'Ghana',
+    'GI' => 'Gibraltar',
+    'GL' => 'Greenland',
+    'GM' => 'Gambia',
+    'GN' => 'Guinea',
+    'GP' => 'Guadeloupe',
+    'GQ' => 'Equatorial Guinea',
+    'GR' => 'Greece',
+    'GS' => 'South Georgia and the South Sandwich Islands',
+    'GT' => 'Guatemala',
+    'GU' => 'Guam',
+    'GW' => 'Guinea-Bissau',
+    'GY' => 'Guyana',
+    'HK' => 'Hong Kong',
+    'HM' => 'Heard Island and McDonald Islands',
+    'HN' => 'Honduras',
+    'HR' => 'Croatia',
+    'HT' => 'Haiti',
+    'HU' => 'Hungary',
+    'ID' => 'Indonesia',
+    'IE' => 'Ireland',
+    'IL' => 'Israel',
+    'IM' => 'Isle of Man',
+    'IN' => 'India',
+    'IO' => 'British Indian Ocean Territory',
+    'IQ' => 'Iraq',
+    'IR' => 'Iran, Islamic Republic of',
+    'IS' => 'Iceland',
+    'IT' => 'Italy',
+    'JE' => 'Jersey',
+    'JM' => 'Jamaica',
+    'JO' => 'Jordan',
+    'JP' => 'Japan',
+    'KE' => 'Kenya',
+    'KG' => 'Kyrgyzstan',
+    'KH' => 'Cambodia',
+    'KI' => 'Kiribati',
+    'KM' => 'Comoros',
+    'KN' => 'Saint Kitts and Nevis',
+    'KP' => "Korea, Democratic People's Republic of",
+    'KR' => 'Korea, Republic of',
+    'KW' => 'Kuwait',
+    'KY' => 'Cayman Islands',
+    'KZ' => 'Kazakhstan',
+    'LA' => "Lao People's Democratic Republic",
+    'LB' => 'Lebanon',
+    'LC' => 'Saint Lucia',
+    'LI' => 'Liechtenstein',
+    'LK' => 'Sri Lanka',
+    'LR' => 'Liberia',
+    'LS' => 'Lesotho',
+    'LT' => 'Lithuania',
+    'LU' => 'Luxembourg',
+    'LV' => 'Latvia',
+    'LY' => 'Libya',
+    'MA' => 'Morocco',
+    'MC' => 'Monaco',
+    'MD' => 'Moldova, Republic of',
+    'ME' => 'Montenegro',
+    'MF' => 'Saint Martin (French part)',
+    'MG' => 'Madagascar',
+    'MH' => 'Marshall Islands',
+    'MK' => 'Macedonia, the Former Yugoslav Republic of',
+    'ML' => 'Mali',
+    'MM' => 'Myanmar',
+    'MN' => 'Mongolia',
+    'MO' => 'Macao',
+    'MP' => 'Northern Mariana Islands',
+    'MQ' => 'Martinique',
+    'MR' => 'Mauritania',
+    'MS' => 'Montserrat',
+    'MT' => 'Malta',
+    'MU' => 'Mauritius',
+    'MV' => 'Maldives',
+    'MW' => 'Malawi',
+    'MX' => 'Mexico',
+    'MY' => 'Malaysia',
+    'MZ' => 'Mozambique',
+    'N/A' => 'Not Applicable (local IP…)',
+    'NA' => 'Namibia',
+    'NC' => 'New Caledonia',
+    'NE' => 'Niger',
+    'NF' => 'Norfolk Island',
+    'NG' => 'Nigeria',
+    'NI' => 'Nicaragua',
+    'NL' => 'Netherlands',
+    'NO' => 'Norway',
+    'NP' => 'Nepal',
+    'NR' => 'Nauru',
+    'NU' => 'Niue',
+    'NZ' => 'New Zealand',
+    'OM' => 'Oman',
+    'PA' => 'Panama',
+    'PE' => 'Peru',
+    'PF' => 'French Polynesia',
+    'PG' => 'Papua New Guinea',
+    'PH' => 'Philippines',
+    'PK' => 'Pakistan',
+    'PL' => 'Poland',
+    'PM' => 'Saint Pierre and Miquelon',
+    'PN' => 'Pitcairn',
+    'PR' => 'Puerto Rico',
+    'PS' => 'Palestine, State of',
+    'PT' => 'Portugal',
+    'PW' => 'Palau',
+    'PY' => 'Paraguay',
+    'QA' => 'Qatar',
+    'RE' => 'Réunion',
+    'RO' => 'Romania',
+    'RS' => 'Serbia',
+    'RU' => 'Russian Federation',
+    'RW' => 'Rwanda',
+    'SA' => 'Saudi Arabia',
+    'SB' => 'Solomon Islands',
+    'SC' => 'Seychelles',
+    'SD' => 'Sudan',
+    'SE' => 'Sweden',
+    'SG' => 'Singapore',
+    'SH' => 'Saint Helena, Ascension and Tristan da Cunha',
+    'SI' => 'Slovenia',
+    'SJ' => 'Svalbard and Jan Mayen',
+    'SK' => 'Slovakia',
+    'SL' => 'Sierra Leone',
+    'SM' => 'San Marino',
+    'SN' => 'Senegal',
+    'SO' => 'Somalia',
+    'SR' => 'Suriname',
+    'SS' => 'South Sudan',
+    'ST' => 'Sao Tome and Principe',
+    'SV' => 'El Salvador',
+    'SX' => 'Sint Maarten (Dutch part)',
+    'SY' => 'Syrian Arab Republic',
+    'SZ' => 'Swaziland',
+    'TC' => 'Turks and Caicos Islands',
+    'TD' => 'Chad',
+    'TF' => 'French Southern Territories',
+    'TG' => 'Togo',
+    'TH' => 'Thailand',
+    'TJ' => 'Tajikistan',
+    'TK' => 'Tokelau',
+    'TL' => 'Timor-Leste',
+    'TM' => 'Turkmenistan',
+    'TN' => 'Tunisia',
+    'TO' => 'Tonga',
+    'TR' => 'Turkey',
+    'TT' => 'Trinidad and Tobago',
+    'TV' => 'Tuvalu',
+    'TW' => 'Taiwan, Province of China',
+    'TZ' => 'Tanzania, United Republic of',
+    'UA' => 'Ukraine',
+    'UG' => 'Uganda',
+    'UM' => 'United States Minor Outlying Islands',
+    'US' => 'United States',
+    'UY' => 'Uruguay',
+    'UZ' => 'Uzbekistan',
+    'VA' => 'Holy See (Vatican City State)',
+    'VC' => 'Saint Vincent and the Grenadines',
+    'VE' => 'Venezuela, Bolivarian Republic of',
+    'VG' => 'Virgin Islands, British',
+    'VI' => 'Virgin Islands, U.S.',
+    'VN' => 'Viet Nam',
+    'VU' => 'Vanuatu',
+    'WF' => 'Wallis and Futuna',
+    'WS' => 'Samoa',
+    'YE' => 'Yemen',
+    'YT' => 'Mayotte',
+    'ZA' => 'South Africa',
+    'ZM' => 'Zambia',
+    'ZW' => 'Zimbabwe',
+];
diff --git a/modules/Admin/Language/eu/Dashboard.php b/modules/Admin/Language/eu/Dashboard.php
new file mode 100644
index 00000000..881073fd
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Episode.php b/modules/Admin/Language/eu/Episode.php
new file mode 100644
index 00000000..4fa846e3
--- /dev/null
+++ b/modules/Admin/Language/eu/Episode.php
@@ -0,0 +1,225 @@
+<?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 [
+    'season' => 'Season {seasonNumber}',
+    'season_abbr' => 'S{seasonNumber}',
+    'number' => 'Episode {episodeNumber}',
+    'number_abbr' => 'Ep. {episodeNumber}',
+    'season_episode' => 'Season {seasonNumber} episode {episodeNumber}',
+    'season_episode_abbr' => 'S{seasonNumber}E{episodeNumber}',
+    'number_of_comments' => '{numberOfComments, plural,
+        one {# comment}
+        other {# comments}
+    }',
+    'all_podcast_episodes' => 'All podcast episodes',
+    'back_to_podcast' => 'Go back to podcast',
+    'edit' => 'Edit',
+    'preview' => 'Preview',
+    'publish' => 'Publish',
+    'publish_edit' => 'Edit publication',
+    'publish_date_edit' => 'Edit publication date',
+    'unpublish' => 'Unpublish',
+    'publish_error' => 'Episode is already published.',
+    'publish_edit_error' => 'Episode is already published.',
+    'publish_cancel_error' => 'Episode is already published.',
+    'publish_date_edit_error' => 'Episode has not been published yet, you cannot edit its publication date.',
+    'publish_date_edit_future_error' => 'Episode\'s publication date can only be set to a past date! If you would like to reschedule it, unpublish it first.',
+    'publish_date_edit_success' => 'Episode\'s publication date has been updated successfully!',
+    'unpublish_error' => 'Episode is not published.',
+    'delete' => 'Delete',
+    'go_to_page' => 'Go to page',
+    'create' => 'Add an episode',
+    'publication_status' => [
+        'published' => 'Published',
+        'with_podcast' => 'Published',
+        'scheduled' => 'Scheduled',
+        'not_published' => 'Not published',
+    ],
+    'with_podcast_hint' => 'To be published at the same time as the podcast',
+    'list' => [
+        'search' => [
+            'placeholder' => 'Search for an episode',
+            'clear' => 'Clear search',
+            'submit' => 'Search',
+        ],
+        'number_of_episodes' => '{numberOfEpisodes, plural,
+            one {# episode}
+            other {# episodes}
+        }',
+        'episode' => 'Episode',
+        'visibility' => 'Visibility',
+        'downloads' => 'Downloads',
+        'comments' => 'Comments',
+        'actions' => 'Actions',
+    ],
+    'messages' => [
+        'createSuccess' => 'Episode has been successfully created!',
+        'editSuccess' => 'Episode has been successfully updated!',
+        'publishSuccess' => '{publication_status, select,
+            published {Episode successfully published!}
+            scheduled {Episode publication successfully scheduled!}
+            with_podcast {This episode will be published at the same time as the podcast.}
+            other {This episode is not published.}
+        }',
+        'publishCancelSuccess' => 'Episode publication successfully cancelled!',
+        'unpublishBeforeDeleteTip' => 'You must unpublish the episode before deleting it.',
+        'scheduleDateError' => 'Schedule date must be set!',
+        'deletePublishedEpisodeError' => 'Please unpublish the episode before deleting it.',
+        'deleteSuccess' => 'Episode successfully deleted!',
+        'deleteError' => 'Failed to delete episode {type, select,
+            transcript {transcript}
+            chapters {chapters}
+            image {cover}
+            audio {audio}
+            other {media}
+        }.',
+        'deleteFileError' => 'Failed to delete {type, select,
+            transcript {transcript}
+            chapters {chapters}
+            image {cover}
+            audio {audio}
+            other {media}
+        } file {file_key}. You may manually remove it from your disk.',
+        'sameSlugError' => 'An episode with the chosen slug already exists.',
+    ],
+    'form' => [
+        'file_size_error' =>
+            'Your file size is too big! Max size is {0}. Increase the `memory_limit`, `upload_max_filesize` and `post_max_size` values in your php configuration file then restart your web server to upload your file.',
+        'audio_file' => 'Audio file',
+        'audio_file_hint' => 'Choose an .mp3 or .m4a audio file.',
+        'info_section_title' => 'Episode info',
+        'cover' => 'Episode cover',
+        'cover_hint' =>
+            'If you do not set a cover, the podcast cover will be used instead.',
+        'cover_size_hint' => 'Cover must be squared and at least 1400px wide and tall.',
+        'title' => 'Title',
+        'title_hint' =>
+            'Should contain a clear and concise episode name. Do not specify the episode or season numbers here.',
+        'permalink' => 'Permalink',
+        'season_number' => 'Season',
+        'episode_number' => 'Episode',
+        'type' => [
+            'label' => 'Type',
+            'full' => 'Full',
+            'full_hint' => 'Complete content (the episode)',
+            'trailer' => 'Trailer',
+            'trailer_hint' => 'Short, promotional piece of content that represents a preview of the current show',
+            'bonus' => 'Bonus',
+            'bonus_hint' => 'Extra content for the show (for example, behind the scenes info or interviews with the cast) or cross-promotional content for another show',
+        ],
+        'premium_title' => 'Premium',
+        'premium' => 'Episode must be accessible to premium subscribers only',
+        'parental_advisory' => [
+            'label' => 'Parental advisory',
+            'hint' => 'Does the episode contain explicit content?',
+            'undefined' => 'undefined',
+            'clean' => 'Clean',
+            'explicit' => 'Explicit',
+        ],
+        'show_notes_section_title' => 'Show notes',
+        'show_notes_section_subtitle' =>
+            'Up to 4000 characters, be clear and concise. Show notes help potential listeners in finding the episode.',
+        'description' => 'Description',
+        'description_footer' => 'Description footer',
+        'description_footer_hint' =>
+            'This text is added at the end of each episode description, it is a good place to input your social links for example.',
+        'additional_files_section_title' => 'Additional files',
+        'additional_files_section_subtitle' =>
+            'These files may be used by other platforms to provide better experience to your audience. See the {podcastNamespaceLink} for more information.',
+        'location_section_title' => 'Location',
+        'location_section_subtitle' => 'What place is this episode about?',
+        'location_name' => 'Location name or address',
+        'location_name_hint' => 'This can be a real or fictional location',
+        'transcript' => 'Transcript (subtitles / closed captions)',
+        'transcript_hint' => 'Only .srt or .vtt are allowed.',
+        'transcript_download' => 'Download transcript',
+        'transcript_file' => 'Transcript file (.srt or .vtt)',
+        'transcript_remote_url' => 'Remote url for transcript',
+        'transcript_file_delete' => 'Delete transcript file',
+        'chapters' => 'Chapters',
+        'chapters_hint' => 'File must be in JSON Chapters format.',
+        'chapters_download' => 'Download chapters',
+        'chapters_file' => 'Chapters file',
+        'chapters_remote_url' => 'Remote url for chapters file',
+        'chapters_file_delete' => 'Delete chapters file',
+        '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 episode',
+        'custom_rss_hint' => 'This will be injected within the ❬item❭ tag.',
+        'block' => 'Episode should be hidden from public catalogues',
+        'block_hint' =>
+            'The episode show or hide status: toggling this on prevents the episode from appearing in Apple Podcasts, Google Podcasts, and any third party apps that pull shows from these directories. (Not guaranteed)',
+        'submit_create' => 'Create episode',
+        'submit_edit' => 'Save episode',
+    ],
+    'publish_form' => [
+        'back_to_episode_dashboard' => 'Back to episode dashboard',
+        'post' => 'Your announcement post',
+        'post_hint' =>
+            "Write a message to announce the publication of your episode. The message will be broadcasted to all your followers in the fediverse and be featured in your podcast's homepage.",
+        'message_placeholder' => 'Write your message…',
+        'publication_date' => 'Publication date',
+        'publication_method' => [
+            'now' => 'Now',
+            'schedule' => 'Schedule',
+            'with_podcast' => 'Publish alongside podcast',
+        ],
+        'scheduled_publication_date' => 'Scheduled publication date',
+        'scheduled_publication_date_clear' => 'Clear publication date',
+        'scheduled_publication_date_hint' =>
+            'You can schedule the episode release by setting a future publication date. This field must be formatted as YYYY-MM-DD HH:mm',
+        'submit' => 'Publish',
+        '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 episode.',
+        'message_warning_submit' => 'Publish anyways',
+    ],
+    'publish_date_edit_form' => [
+        'new_publication_date' => 'New publication date',
+        'new_publication_date_hint' => 'Must be set to a past date.',
+        'submit' => 'Edit publication date',
+    ],
+    'unpublish_form' => [
+        'disclaimer' =>
+            "Unpublishing the episode will delete all the comments and posts associated with it and remove it from the podcast's RSS feed.",
+        'understand' => 'I understand, I want to unpublish the episode',
+        'submit' => 'Unpublish',
+    ],
+    'delete_form' => [
+        'disclaimer' =>
+            "Deleting the episode will delete all media files, comments, video clips and soundbites associated with it.",
+        'understand' => 'I understand, I want to delete the episode',
+        'submit' => 'Delete',
+    ],
+    'embed' => [
+        'title' => 'Embeddable player',
+        'label' =>
+            'Pick a theme color, copy the embeddable player to clipboard, then paste it on your website.',
+        'clipboard_iframe' => 'Copy embeddable player to clipboard',
+        'clipboard_url' => 'Copy address to clipboard',
+        'dark' => 'Dark',
+        'dark-transparent' => 'Dark transparent',
+        'light' => 'Light',
+        'light-transparent' => 'Light transparent',
+    ],
+    'publication_status_banner' => [
+        'draft_mode' => 'draft mode',
+        'text' => '{publication_status, select,
+            published {This episode is not yet published.}
+            scheduled {This episode is scheduled for publication on {publication_date}.}
+            with_podcast {This episode will be published at the same time as the podcast.}
+            other {This episode is not yet published.}
+        }',
+        'preview' => 'Preview',
+    ],
+];
diff --git a/modules/Admin/Language/eu/EpisodeNavigation.php b/modules/Admin/Language/eu/EpisodeNavigation.php
new file mode 100644
index 00000000..1406e301
--- /dev/null
+++ b/modules/Admin/Language/eu/EpisodeNavigation.php
@@ -0,0 +1,23 @@
+<?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' => 'View episode page',
+    'dashboard' => 'Episode dashboard',
+    'episode-view' => 'Home',
+    'episode-edit' => 'Edit episode',
+    'episode-persons-manage' => 'Manage persons',
+    'embed-add' => 'Embeddable player',
+    'clips' => 'Clips',
+    'video-clips-list' => 'Video clips',
+    'video-clips-create' => 'New video clip',
+    'soundbites-list' => 'Soundbites',
+    'soundbites-create' => 'New soundbite',
+];
diff --git a/modules/Admin/Language/eu/Fediverse.php b/modules/Admin/Language/eu/Fediverse.php
new file mode 100644
index 00000000..0e4ca66d
--- /dev/null
+++ b/modules/Admin/Language/eu/Fediverse.php
@@ -0,0 +1,32 @@
+<?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 [
+    'messages' => [
+        'actorNotFound' => 'The account could not be found!',
+        'blockActorSuccess' => '{actor} has been blocked!',
+        'unblockActorSuccess' => 'Actor has been unblocked!',
+        'blockDomainSuccess' => '{domain} has been blocked!',
+        'unblockDomainSuccess' => '{domain} has been unblocked!',
+    ],
+    'blocked_actors' => 'Blocked accounts',
+    'blocked_domains' => 'Blocked domains',
+    'block_lists_form' => [
+        'handle' => 'Account handle',
+        'handle_hint' => 'Input @username@domain account.',
+        'domain' => 'Domain name',
+        'submit' => 'Block!',
+    ],
+    'list' => [
+        'actor' => 'Account',
+        'domain' => 'Domain name',
+        'unblock' => 'Unblock',
+    ],
+];
diff --git a/modules/Admin/Language/eu/Home.php b/modules/Admin/Language/eu/Home.php
new file mode 100644
index 00000000..3ff4c04d
--- /dev/null
+++ b/modules/Admin/Language/eu/Home.php
@@ -0,0 +1,14 @@
+<?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',
+];
diff --git a/modules/Admin/Language/eu/Install.php b/modules/Admin/Language/eu/Install.php
new file mode 100644
index 00000000..36e373a2
--- /dev/null
+++ b/modules/Admin/Language/eu/Install.php
@@ -0,0 +1,61 @@
+<?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 [
+    '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 superadmin 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/Admin/Language/eu/Navigation.php b/modules/Admin/Language/eu/Navigation.php
new file mode 100644
index 00000000..f3ffb129
--- /dev/null
+++ b/modules/Admin/Language/eu/Navigation.php
@@ -0,0 +1,44 @@
+<?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',
+    'not-authorized' => 'Not authorized',
+    'dashboard' => 'Dashboard',
+    'admin' => 'Home',
+    'podcasts' => 'Podcasts',
+    'podcast-list' => 'All podcasts',
+    'podcast-create' => 'New podcast',
+    'all-podcast-imports' => 'All Podcast imports',
+    'podcast-imports-add' => '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',
+    'admin-about' => 'About',
+    'account' => [
+        'my-account' => 'My account',
+        'change-password' => 'Change password',
+        'logout' => 'Logout',
+    ],
+];
diff --git a/modules/Admin/Language/eu/Notifications.php b/modules/Admin/Language/eu/Notifications.php
new file mode 100644
index 00000000..2b139d51
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Page.php b/modules/Admin/Language/eu/Page.php
new file mode 100644
index 00000000..b6f49de5
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Pager.php b/modules/Admin/Language/eu/Pager.php
new file mode 100644
index 00000000..e25ee638
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Person.php b/modules/Admin/Language/eu/Person.php
new file mode 100644
index 00000000..a652be9f
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Platforms.php b/modules/Admin/Language/eu/Platforms.php
new file mode 100644
index 00000000..e161181c
--- /dev/null
+++ b/modules/Admin/Language/eu/Platforms.php
@@ -0,0 +1,43 @@
+<?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' => [
+        'podcasting' => 'Podcasting platforms',
+        'social' => 'Social networks',
+        'funding' => 'Funding links',
+    ],
+    'website' => 'Website',
+    'home_url' => 'Go to {platformName} website',
+    'register' => 'Register',
+    'submit_url' => 'Submit your podcast on {platformName}',
+    'your_link' => 'Your link',
+    'your_id' => [
+        'podcasting' => 'Your ID',
+        'social' => 'Your ID',
+        'funding' => 'Your CTA',
+    ],
+    'your_cta' => 'Your call to action',
+    '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/eu/Podcast.php b/modules/Admin/Language/eu/Podcast.php
new file mode 100644
index 00000000..d02b6cf4
--- /dev/null
+++ b/modules/Admin/Language/eu/Podcast.php
@@ -0,0 +1,327 @@
+<?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',
+    'all_imports' => 'Podcast imports',
+    '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',
+    'monetization_other' => 'Other monetization',
+    '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.',
+        '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.',
+        'fediverse_section_title' => 'Fediverse identity',
+
+        '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. Episodes will be presented in numeric order.',
+        ],
+        'medium' => [
+            'label' => 'Medium',
+            'hint' => 'Medium as represented by podcast:medium tag in RSS. Changing this may change how players present your feed.',
+            'podcast' => 'Podcast',
+            'podcast_hint' => 'Describes a feed for a podcast show.',
+            'music' => 'Music',
+            'music_hint' => 'A feed of music organized into an "album" with each item a song within the album.',
+            'audiobook' => 'Audiobook',
+            'audiobook_hint' => 'Specific types of audio with one item per feed, or where items represent chapters within the book.',
+        ],
+        '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.',
+        'is_owner_email_removed_from_feed' => 'Remove the owner email from the public RSS feed',
+        'is_owner_email_removed_from_feed_hint' => 'You may need to temporarily unhide the email so that a directory can verify your podcast ownership.',
+        '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_link' => 'Visit your OP3 dashboard (external link)',
+        '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',
+        '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',
+        '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/eu/PodcastNavigation.php b/modules/Admin/Language/eu/PodcastNavigation.php
new file mode 100644
index 00000000..bb777707
--- /dev/null
+++ b/modules/Admin/Language/eu/PodcastNavigation.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 [
+    'go_to_page' => 'Go to podcast page',
+    'rss_feed' => 'RSS feed',
+    'dashboard' => 'Podcast dashboard',
+    'podcast-view' => 'Home',
+    'podcast-edit' => 'Edit podcast',
+    'podcast-persons-manage' => 'Manage persons',
+    'podcast-imports' => 'Podcast imports',
+    'podcast-imports-sync' => 'Sync feeds',
+    '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',
+    'monetization' => 'Monetization',
+    'subscription-list' => 'All subscriptions',
+    'subscription-create' => 'Add subscription',
+    'contributors' => 'Contributors',
+    'contributor-list' => 'All contributors',
+    'contributor-add' => 'Add contributor',
+    'broadcast' => 'Broadcast',
+    'platforms-podcasting' => 'Podcasting apps',
+    'platforms-social' => 'Social networks',
+    'platforms-funding' => 'Funding links',
+    'podcast-monetization-other' => 'Other',
+];
diff --git a/modules/Admin/Language/eu/Settings.php b/modules/Admin/Language/eu/Settings.php
new file mode 100644
index 00000000..4a70dcba
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Soundbite.php b/modules/Admin/Language/eu/Soundbite.php
new file mode 100644
index 00000000..a3f828fe
--- /dev/null
+++ b/modules/Admin/Language/eu/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/eu/Validation.php b/modules/Admin/Language/eu/Validation.php
new file mode 100644
index 00000000..f76c3163
--- /dev/null
+++ b/modules/Admin/Language/eu/Validation.php
@@ -0,0 +1,17 @@
+<?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.',
+    'is_json' => '{field} contains invalid JSON.',
+];
diff --git a/modules/Admin/Language/eu/VideoClip.php b/modules/Admin/Language/eu/VideoClip.php
new file mode 100644
index 00000000..638de697
--- /dev/null
+++ b/modules/Admin/Language/eu/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/ja/AboutCastopod.php b/modules/Admin/Language/ja/AboutCastopod.php
index 3fb62aff..16c3c2b2 100644
--- a/modules/Admin/Language/ja/AboutCastopod.php
+++ b/modules/Admin/Language/ja/AboutCastopod.php
@@ -9,14 +9,14 @@ declare(strict_types=1);
  */
 
 return [
-    'title' => 'About Castopod',
-    'host_name' => 'Host name',
-    'version' => 'Castopod version',
-    'php_version' => 'PHP version',
-    'os' => 'Operating System',
-    'languages' => 'Languages',
-    'update_database' => 'Update database',
+    'title' => 'Castopodについて',
+    'host_name' => 'ホスト名',
+    'version' => 'Castopodバージョン',
+    'php_version' => 'PHPバージョン',
+    'os' => '(OS) オペレーティング システム',
+    'languages' => '言語',
+    'update_database' => 'データベースを更新',
     'messages' => [
-        'databaseUpdateSuccess' => 'Database is up to date!',
+        'databaseUpdateSuccess' => 'データベースは最新です',
     ],
 ];
diff --git a/modules/Admin/Language/pt-BR/Podcast.php b/modules/Admin/Language/pt-BR/Podcast.php
index 496313c3..67e889d6 100644
--- a/modules/Admin/Language/pt-BR/Podcast.php
+++ b/modules/Admin/Language/pt-BR/Podcast.php
@@ -74,7 +74,7 @@ return [
             'episodic' => 'Episódico',
             'episodic_hint' => 'Se os episódios são destinados a serem consumidos sem qualquer ordem específica. Os episódios mais recentes serão apresentados primeiro.',
             'serial' => 'Serial',
-            'serial_hint' => 'If episodes are intended to be consumed in sequential order. Episodes will be presented in numeric order.',
+            'serial_hint' => 'Se a intenção é que os episódios sejam consumidos em uma ordem sequencial. Episódios vão ser apresentados em uma ordem numérica.',
         ],
         'medium' => [
             'label' => 'Medium',
diff --git a/modules/Admin/Language/zh-Hant/AboutCastopod.php b/modules/Admin/Language/zh-Hant/AboutCastopod.php
new file mode 100644
index 00000000..3fb62aff
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Breadcrumb.php b/modules/Admin/Language/zh-Hant/Breadcrumb.php
new file mode 100644
index 00000000..6a678d4e
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Breadcrumb.php
@@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+use Modules\Admin\Config\Admin;
+
+/**
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'label' => 'breadcrumb',
+    config(Admin::class)
+        ->gateway => 'Home',
+    'podcasts' => 'podcasts',
+    'episodes' => 'episodes',
+    'subscriptions' => 'subscriptions',
+    'contributors' => 'contributors',
+    'pages' => 'pages',
+    'settings' => 'settings',
+    'theme' => 'theme',
+    'about' => 'about',
+    'add' => 'add',
+    'new' => 'new',
+    'edit' => 'edit',
+    'persons' => 'persons',
+    'publish' => 'publish',
+    'publish-edit' => 'edit publication',
+    'publish-date-edit' => 'edit publication date',
+    'unpublish' => 'unpublish',
+    'delete' => 'delete',
+    'remove' => 'remove',
+    'fediverse' => 'fediverse',
+    'blocked-actors' => 'blocked actors',
+    'blocked-domains' => 'blocked domains',
+    'users' => 'users',
+    'my-account' => 'my account',
+    'change-password' => 'change password',
+    'imports' => 'imports',
+    'sync-feeds' => 'synchronize feeds',
+    'platforms' => 'platforms',
+    'social' => 'social networks',
+    'funding' => 'funding',
+    'monetization-other' => 'other monetization',
+    'analytics' => 'analytics',
+    'locations' => 'locations',
+    'webpages' => 'web pages',
+    'unique-listeners' => 'unique listeners',
+    'players' => 'players',
+    'listening-time' => 'listening time',
+    'time-periods' => 'time periods',
+    'soundbites' => 'soundbites',
+    'video-clips' => 'video clips',
+    'embed' => 'embeddable player',
+    'notifications' => 'notifications',
+    'suspend' => 'suspend',
+];
diff --git a/modules/Admin/Language/zh-Hant/Charts.php b/modules/Admin/Language/zh-Hant/Charts.php
new file mode 100644
index 00000000..6ede2510
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Charts.php
@@ -0,0 +1,41 @@
+<?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 [
+    'by_service_weekly' => 'Episode downloads by service (for the past week)',
+    'by_player_weekly' => 'Episode downloads by player (for the past week)',
+    'by_player_yearly' => 'Episode downloads by player (for the past year)',
+    'by_device_weekly' => 'Episode downloads by device (for the past week)',
+    'by_os_weekly' => 'Episode downloads by O.S. (for the past week)',
+    'podcast_by_region' => 'Episode downloads by region (for the past week)',
+    'unique_daily_listeners' => 'Daily unique listeners',
+    'unique_monthly_listeners' => 'Monthly unique listeners',
+    'by_browser' => 'Web pages usage by browser (for the past week)',
+    'podcast_by_day' => 'Episode daily downloads',
+    'podcast_by_month' => 'Episode monthly downloads',
+    'episode_by_day' => 'Episode daily downloads (first 60 days)',
+    'episode_by_month' => 'Episode monthly downloads',
+    'episodes_by_day' =>
+        '5 latest episodes downloads (during their first 60 days)',
+    'by_country_weekly' => 'Episode downloads by country (for the past week)',
+    'by_country_yearly' => 'Episode downloads by country (for the past year)',
+    'by_domain_weekly' => 'Web pages visits by source (for the past week)',
+    'by_domain_yearly' => 'Web pages visits by source (for the past year)',
+    'by_entry_page' => 'Web pages visits by landing page (for the past week)',
+    'podcast_bots' => 'Bots (crawlers)',
+    'daily_listening_time' => 'Daily cumulative listening time',
+    'monthly_listening_time' => 'Monthly cumulative listening time',
+    'by_weekday' => 'By week day (for the past 60 days)',
+    'by_hour' => 'By time of day (for the past 60 days)',
+    'podcast_by_bandwidth' => 'Daily used bandwidth (in MB)',
+    'total_storage_by_month' => 'Monthly storage (in MB)',
+    'total_bandwidth_by_month' => 'Monthly used bandwidth (in MB)',
+    'total_bandwidth_by_month_limit' => 'Limited to {totalBandwidth} per month',
+];
diff --git a/modules/Admin/Language/zh-Hant/Common.php b/modules/Admin/Language/zh-Hant/Common.php
new file mode 100644
index 00000000..74addcf2
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Common.php
@@ -0,0 +1,52 @@
+<?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 [
+    'yes' => 'Yes',
+    'no' => 'No',
+    'cancel' => 'Cancel',
+    'optional' => 'Optional',
+    'more' => 'More',
+    'no_data' => 'No data found!',
+    'close' => 'Close',
+    'edit' => 'Edit',
+    'copy' => 'Copy',
+    'copied' => 'Copied!',
+    'home' => 'Home',
+    'explicit' => 'Explicit',
+    'powered_by' => 'Powered by {castopod}',
+    'actions' => 'Actions',
+    'pageInfo' => 'Page {currentPage} out of {pageCount}',
+    'go_back' => 'Go back',
+    'forms' => [
+        'editor' => [
+            'write' => 'Write',
+            'preview' => 'Preview',
+            'help' => 'Powered by markdown',
+        ],
+        'multiSelect' => [
+            'selectText' => 'Press to select',
+            'loadingText' => 'Loading…',
+            'noResultsText' => 'No results found',
+            'noChoicesText' => 'No choices to choose from',
+            'maxItemText' => 'Cannot add more items',
+        ],
+        'upload_file' => 'Upload a file',
+        'remote_url' => 'Remote URL',
+        'save' => 'Save',
+    ],
+    'play_episode_button' => [
+        'play' => 'Play',
+        'playing' => 'Playing',
+    ],
+    'size_limit' => 'Size limit: {0}.',
+    'choose_interact' => 'Choose how to interact',
+    'view' => 'View',
+];
diff --git a/modules/Admin/Language/zh-Hant/Countries.php b/modules/Admin/Language/zh-Hant/Countries.php
new file mode 100644
index 00000000..4cd5d9c8
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Countries.php
@@ -0,0 +1,264 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * ISO 3166 country codes
+ *
+ * @copyright  2020 Ad Aures
+ * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
+ * @link       https://castopod.org/
+ */
+
+return [
+    'AD' => 'Andorra',
+    'AE' => 'United Arab Emirates',
+    'AF' => 'Afghanistan',
+    'AG' => 'Antigua and Barbuda',
+    'AI' => 'Anguilla',
+    'AL' => 'Albania',
+    'AM' => 'Armenia',
+    'AO' => 'Angola',
+    'AQ' => 'Antarctica',
+    'AR' => 'Argentina',
+    'AS' => 'American Samoa',
+    'AT' => 'Austria',
+    'AU' => 'Australia',
+    'AW' => 'Aruba',
+    'AX' => 'Åland Islands',
+    'AZ' => 'Azerbaijan',
+    'BA' => 'Bosnia and Herzegovina',
+    'BB' => 'Barbados',
+    'BD' => 'Bangladesh',
+    'BE' => 'Belgium',
+    'BF' => 'Burkina Faso',
+    'BG' => 'Bulgaria',
+    'BH' => 'Bahrain',
+    'BI' => 'Burundi',
+    'BJ' => 'Benin',
+    'BL' => 'Saint Barthélemy',
+    'BM' => 'Bermuda',
+    'BN' => 'Brunei Darussalam',
+    'BO' => 'Bolivia, Plurinational State of',
+    'BQ' => 'Bonaire, Sint Eustatius and Saba',
+    'BR' => 'Brazil',
+    'BS' => 'Bahamas',
+    'BT' => 'Bhutan',
+    'BV' => 'Bouvet Island',
+    'BW' => 'Botswana',
+    'BY' => 'Belarus',
+    'BZ' => 'Belize',
+    'CA' => 'Canada',
+    'CC' => 'Cocos (Keeling) Islands',
+    'CD' => 'Congo, the Democratic Republic of the',
+    'CF' => 'Central African Republic',
+    'CG' => 'Congo',
+    'CH' => 'Switzerland',
+    'CI' => "Côte d'Ivoire",
+    'CK' => 'Cook Islands',
+    'CL' => 'Chile',
+    'CM' => 'Cameroon',
+    'CN' => 'China',
+    'CO' => 'Colombia',
+    'CR' => 'Costa Rica',
+    'CU' => 'Cuba',
+    'CV' => 'Cape Verde',
+    'CW' => 'Curaçao',
+    'CX' => 'Christmas Island',
+    'CY' => 'Cyprus',
+    'CZ' => 'Czech Republic',
+    'DE' => 'Germany',
+    'DJ' => 'Djibouti',
+    'DK' => 'Denmark',
+    'DM' => 'Dominica',
+    'DO' => 'Dominican Republic',
+    'DZ' => 'Algeria',
+    'EC' => 'Ecuador',
+    'EE' => 'Estonia',
+    'EG' => 'Egypt',
+    'EH' => 'Western Sahara',
+    'ER' => 'Eritrea',
+    'ES' => 'Spain',
+    'ET' => 'Ethiopia',
+    'FI' => 'Finland',
+    'FJ' => 'Fiji',
+    'FK' => 'Falkland Islands (Malvinas)',
+    'FM' => 'Micronesia, Federated States of',
+    'FO' => 'Faroe Islands',
+    'FR' => 'France',
+    'GA' => 'Gabon',
+    'GB' => 'United Kingdom',
+    'GD' => 'Grenada',
+    'GE' => 'Georgia',
+    'GF' => 'French Guiana',
+    'GG' => 'Guernsey',
+    'GH' => 'Ghana',
+    'GI' => 'Gibraltar',
+    'GL' => 'Greenland',
+    'GM' => 'Gambia',
+    'GN' => 'Guinea',
+    'GP' => 'Guadeloupe',
+    'GQ' => 'Equatorial Guinea',
+    'GR' => 'Greece',
+    'GS' => 'South Georgia and the South Sandwich Islands',
+    'GT' => 'Guatemala',
+    'GU' => 'Guam',
+    'GW' => 'Guinea-Bissau',
+    'GY' => 'Guyana',
+    'HK' => 'Hong Kong',
+    'HM' => 'Heard Island and McDonald Islands',
+    'HN' => 'Honduras',
+    'HR' => 'Croatia',
+    'HT' => 'Haiti',
+    'HU' => 'Hungary',
+    'ID' => 'Indonesia',
+    'IE' => 'Ireland',
+    'IL' => 'Israel',
+    'IM' => 'Isle of Man',
+    'IN' => 'India',
+    'IO' => 'British Indian Ocean Territory',
+    'IQ' => 'Iraq',
+    'IR' => 'Iran, Islamic Republic of',
+    'IS' => 'Iceland',
+    'IT' => 'Italy',
+    'JE' => 'Jersey',
+    'JM' => 'Jamaica',
+    'JO' => 'Jordan',
+    'JP' => 'Japan',
+    'KE' => 'Kenya',
+    'KG' => 'Kyrgyzstan',
+    'KH' => 'Cambodia',
+    'KI' => 'Kiribati',
+    'KM' => 'Comoros',
+    'KN' => 'Saint Kitts and Nevis',
+    'KP' => "Korea, Democratic People's Republic of",
+    'KR' => 'Korea, Republic of',
+    'KW' => 'Kuwait',
+    'KY' => 'Cayman Islands',
+    'KZ' => 'Kazakhstan',
+    'LA' => "Lao People's Democratic Republic",
+    'LB' => 'Lebanon',
+    'LC' => 'Saint Lucia',
+    'LI' => 'Liechtenstein',
+    'LK' => 'Sri Lanka',
+    'LR' => 'Liberia',
+    'LS' => 'Lesotho',
+    'LT' => 'Lithuania',
+    'LU' => 'Luxembourg',
+    'LV' => 'Latvia',
+    'LY' => 'Libya',
+    'MA' => 'Morocco',
+    'MC' => 'Monaco',
+    'MD' => 'Moldova, Republic of',
+    'ME' => 'Montenegro',
+    'MF' => 'Saint Martin (French part)',
+    'MG' => 'Madagascar',
+    'MH' => 'Marshall Islands',
+    'MK' => 'Macedonia, the Former Yugoslav Republic of',
+    'ML' => 'Mali',
+    'MM' => 'Myanmar',
+    'MN' => 'Mongolia',
+    'MO' => 'Macao',
+    'MP' => 'Northern Mariana Islands',
+    'MQ' => 'Martinique',
+    'MR' => 'Mauritania',
+    'MS' => 'Montserrat',
+    'MT' => 'Malta',
+    'MU' => 'Mauritius',
+    'MV' => 'Maldives',
+    'MW' => 'Malawi',
+    'MX' => 'Mexico',
+    'MY' => 'Malaysia',
+    'MZ' => 'Mozambique',
+    'N/A' => 'Not Applicable (local IP…)',
+    'NA' => 'Namibia',
+    'NC' => 'New Caledonia',
+    'NE' => 'Niger',
+    'NF' => 'Norfolk Island',
+    'NG' => 'Nigeria',
+    'NI' => 'Nicaragua',
+    'NL' => 'Netherlands',
+    'NO' => 'Norway',
+    'NP' => 'Nepal',
+    'NR' => 'Nauru',
+    'NU' => 'Niue',
+    'NZ' => 'New Zealand',
+    'OM' => 'Oman',
+    'PA' => 'Panama',
+    'PE' => 'Peru',
+    'PF' => 'French Polynesia',
+    'PG' => 'Papua New Guinea',
+    'PH' => 'Philippines',
+    'PK' => 'Pakistan',
+    'PL' => 'Poland',
+    'PM' => 'Saint Pierre and Miquelon',
+    'PN' => 'Pitcairn',
+    'PR' => 'Puerto Rico',
+    'PS' => 'Palestine, State of',
+    'PT' => 'Portugal',
+    'PW' => 'Palau',
+    'PY' => 'Paraguay',
+    'QA' => 'Qatar',
+    'RE' => 'Réunion',
+    'RO' => 'Romania',
+    'RS' => 'Serbia',
+    'RU' => 'Russian Federation',
+    'RW' => 'Rwanda',
+    'SA' => 'Saudi Arabia',
+    'SB' => 'Solomon Islands',
+    'SC' => 'Seychelles',
+    'SD' => 'Sudan',
+    'SE' => 'Sweden',
+    'SG' => 'Singapore',
+    'SH' => 'Saint Helena, Ascension and Tristan da Cunha',
+    'SI' => 'Slovenia',
+    'SJ' => 'Svalbard and Jan Mayen',
+    'SK' => 'Slovakia',
+    'SL' => 'Sierra Leone',
+    'SM' => 'San Marino',
+    'SN' => 'Senegal',
+    'SO' => 'Somalia',
+    'SR' => 'Suriname',
+    'SS' => 'South Sudan',
+    'ST' => 'Sao Tome and Principe',
+    'SV' => 'El Salvador',
+    'SX' => 'Sint Maarten (Dutch part)',
+    'SY' => 'Syrian Arab Republic',
+    'SZ' => 'Swaziland',
+    'TC' => 'Turks and Caicos Islands',
+    'TD' => 'Chad',
+    'TF' => 'French Southern Territories',
+    'TG' => 'Togo',
+    'TH' => 'Thailand',
+    'TJ' => 'Tajikistan',
+    'TK' => 'Tokelau',
+    'TL' => 'Timor-Leste',
+    'TM' => 'Turkmenistan',
+    'TN' => 'Tunisia',
+    'TO' => 'Tonga',
+    'TR' => 'Turkey',
+    'TT' => 'Trinidad and Tobago',
+    'TV' => 'Tuvalu',
+    'TW' => 'Taiwan, Province of China',
+    'TZ' => 'Tanzania, United Republic of',
+    'UA' => 'Ukraine',
+    'UG' => 'Uganda',
+    'UM' => 'United States Minor Outlying Islands',
+    'US' => 'United States',
+    'UY' => 'Uruguay',
+    'UZ' => 'Uzbekistan',
+    'VA' => 'Holy See (Vatican City State)',
+    'VC' => 'Saint Vincent and the Grenadines',
+    'VE' => 'Venezuela, Bolivarian Republic of',
+    'VG' => 'Virgin Islands, British',
+    'VI' => 'Virgin Islands, U.S.',
+    'VN' => 'Viet Nam',
+    'VU' => 'Vanuatu',
+    'WF' => 'Wallis and Futuna',
+    'WS' => 'Samoa',
+    'YE' => 'Yemen',
+    'YT' => 'Mayotte',
+    'ZA' => 'South Africa',
+    'ZM' => 'Zambia',
+    'ZW' => 'Zimbabwe',
+];
diff --git a/modules/Admin/Language/zh-Hant/Dashboard.php b/modules/Admin/Language/zh-Hant/Dashboard.php
new file mode 100644
index 00000000..881073fd
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Episode.php b/modules/Admin/Language/zh-Hant/Episode.php
new file mode 100644
index 00000000..4fa846e3
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Episode.php
@@ -0,0 +1,225 @@
+<?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 [
+    'season' => 'Season {seasonNumber}',
+    'season_abbr' => 'S{seasonNumber}',
+    'number' => 'Episode {episodeNumber}',
+    'number_abbr' => 'Ep. {episodeNumber}',
+    'season_episode' => 'Season {seasonNumber} episode {episodeNumber}',
+    'season_episode_abbr' => 'S{seasonNumber}E{episodeNumber}',
+    'number_of_comments' => '{numberOfComments, plural,
+        one {# comment}
+        other {# comments}
+    }',
+    'all_podcast_episodes' => 'All podcast episodes',
+    'back_to_podcast' => 'Go back to podcast',
+    'edit' => 'Edit',
+    'preview' => 'Preview',
+    'publish' => 'Publish',
+    'publish_edit' => 'Edit publication',
+    'publish_date_edit' => 'Edit publication date',
+    'unpublish' => 'Unpublish',
+    'publish_error' => 'Episode is already published.',
+    'publish_edit_error' => 'Episode is already published.',
+    'publish_cancel_error' => 'Episode is already published.',
+    'publish_date_edit_error' => 'Episode has not been published yet, you cannot edit its publication date.',
+    'publish_date_edit_future_error' => 'Episode\'s publication date can only be set to a past date! If you would like to reschedule it, unpublish it first.',
+    'publish_date_edit_success' => 'Episode\'s publication date has been updated successfully!',
+    'unpublish_error' => 'Episode is not published.',
+    'delete' => 'Delete',
+    'go_to_page' => 'Go to page',
+    'create' => 'Add an episode',
+    'publication_status' => [
+        'published' => 'Published',
+        'with_podcast' => 'Published',
+        'scheduled' => 'Scheduled',
+        'not_published' => 'Not published',
+    ],
+    'with_podcast_hint' => 'To be published at the same time as the podcast',
+    'list' => [
+        'search' => [
+            'placeholder' => 'Search for an episode',
+            'clear' => 'Clear search',
+            'submit' => 'Search',
+        ],
+        'number_of_episodes' => '{numberOfEpisodes, plural,
+            one {# episode}
+            other {# episodes}
+        }',
+        'episode' => 'Episode',
+        'visibility' => 'Visibility',
+        'downloads' => 'Downloads',
+        'comments' => 'Comments',
+        'actions' => 'Actions',
+    ],
+    'messages' => [
+        'createSuccess' => 'Episode has been successfully created!',
+        'editSuccess' => 'Episode has been successfully updated!',
+        'publishSuccess' => '{publication_status, select,
+            published {Episode successfully published!}
+            scheduled {Episode publication successfully scheduled!}
+            with_podcast {This episode will be published at the same time as the podcast.}
+            other {This episode is not published.}
+        }',
+        'publishCancelSuccess' => 'Episode publication successfully cancelled!',
+        'unpublishBeforeDeleteTip' => 'You must unpublish the episode before deleting it.',
+        'scheduleDateError' => 'Schedule date must be set!',
+        'deletePublishedEpisodeError' => 'Please unpublish the episode before deleting it.',
+        'deleteSuccess' => 'Episode successfully deleted!',
+        'deleteError' => 'Failed to delete episode {type, select,
+            transcript {transcript}
+            chapters {chapters}
+            image {cover}
+            audio {audio}
+            other {media}
+        }.',
+        'deleteFileError' => 'Failed to delete {type, select,
+            transcript {transcript}
+            chapters {chapters}
+            image {cover}
+            audio {audio}
+            other {media}
+        } file {file_key}. You may manually remove it from your disk.',
+        'sameSlugError' => 'An episode with the chosen slug already exists.',
+    ],
+    'form' => [
+        'file_size_error' =>
+            'Your file size is too big! Max size is {0}. Increase the `memory_limit`, `upload_max_filesize` and `post_max_size` values in your php configuration file then restart your web server to upload your file.',
+        'audio_file' => 'Audio file',
+        'audio_file_hint' => 'Choose an .mp3 or .m4a audio file.',
+        'info_section_title' => 'Episode info',
+        'cover' => 'Episode cover',
+        'cover_hint' =>
+            'If you do not set a cover, the podcast cover will be used instead.',
+        'cover_size_hint' => 'Cover must be squared and at least 1400px wide and tall.',
+        'title' => 'Title',
+        'title_hint' =>
+            'Should contain a clear and concise episode name. Do not specify the episode or season numbers here.',
+        'permalink' => 'Permalink',
+        'season_number' => 'Season',
+        'episode_number' => 'Episode',
+        'type' => [
+            'label' => 'Type',
+            'full' => 'Full',
+            'full_hint' => 'Complete content (the episode)',
+            'trailer' => 'Trailer',
+            'trailer_hint' => 'Short, promotional piece of content that represents a preview of the current show',
+            'bonus' => 'Bonus',
+            'bonus_hint' => 'Extra content for the show (for example, behind the scenes info or interviews with the cast) or cross-promotional content for another show',
+        ],
+        'premium_title' => 'Premium',
+        'premium' => 'Episode must be accessible to premium subscribers only',
+        'parental_advisory' => [
+            'label' => 'Parental advisory',
+            'hint' => 'Does the episode contain explicit content?',
+            'undefined' => 'undefined',
+            'clean' => 'Clean',
+            'explicit' => 'Explicit',
+        ],
+        'show_notes_section_title' => 'Show notes',
+        'show_notes_section_subtitle' =>
+            'Up to 4000 characters, be clear and concise. Show notes help potential listeners in finding the episode.',
+        'description' => 'Description',
+        'description_footer' => 'Description footer',
+        'description_footer_hint' =>
+            'This text is added at the end of each episode description, it is a good place to input your social links for example.',
+        'additional_files_section_title' => 'Additional files',
+        'additional_files_section_subtitle' =>
+            'These files may be used by other platforms to provide better experience to your audience. See the {podcastNamespaceLink} for more information.',
+        'location_section_title' => 'Location',
+        'location_section_subtitle' => 'What place is this episode about?',
+        'location_name' => 'Location name or address',
+        'location_name_hint' => 'This can be a real or fictional location',
+        'transcript' => 'Transcript (subtitles / closed captions)',
+        'transcript_hint' => 'Only .srt or .vtt are allowed.',
+        'transcript_download' => 'Download transcript',
+        'transcript_file' => 'Transcript file (.srt or .vtt)',
+        'transcript_remote_url' => 'Remote url for transcript',
+        'transcript_file_delete' => 'Delete transcript file',
+        'chapters' => 'Chapters',
+        'chapters_hint' => 'File must be in JSON Chapters format.',
+        'chapters_download' => 'Download chapters',
+        'chapters_file' => 'Chapters file',
+        'chapters_remote_url' => 'Remote url for chapters file',
+        'chapters_file_delete' => 'Delete chapters file',
+        '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 episode',
+        'custom_rss_hint' => 'This will be injected within the ❬item❭ tag.',
+        'block' => 'Episode should be hidden from public catalogues',
+        'block_hint' =>
+            'The episode show or hide status: toggling this on prevents the episode from appearing in Apple Podcasts, Google Podcasts, and any third party apps that pull shows from these directories. (Not guaranteed)',
+        'submit_create' => 'Create episode',
+        'submit_edit' => 'Save episode',
+    ],
+    'publish_form' => [
+        'back_to_episode_dashboard' => 'Back to episode dashboard',
+        'post' => 'Your announcement post',
+        'post_hint' =>
+            "Write a message to announce the publication of your episode. The message will be broadcasted to all your followers in the fediverse and be featured in your podcast's homepage.",
+        'message_placeholder' => 'Write your message…',
+        'publication_date' => 'Publication date',
+        'publication_method' => [
+            'now' => 'Now',
+            'schedule' => 'Schedule',
+            'with_podcast' => 'Publish alongside podcast',
+        ],
+        'scheduled_publication_date' => 'Scheduled publication date',
+        'scheduled_publication_date_clear' => 'Clear publication date',
+        'scheduled_publication_date_hint' =>
+            'You can schedule the episode release by setting a future publication date. This field must be formatted as YYYY-MM-DD HH:mm',
+        'submit' => 'Publish',
+        '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 episode.',
+        'message_warning_submit' => 'Publish anyways',
+    ],
+    'publish_date_edit_form' => [
+        'new_publication_date' => 'New publication date',
+        'new_publication_date_hint' => 'Must be set to a past date.',
+        'submit' => 'Edit publication date',
+    ],
+    'unpublish_form' => [
+        'disclaimer' =>
+            "Unpublishing the episode will delete all the comments and posts associated with it and remove it from the podcast's RSS feed.",
+        'understand' => 'I understand, I want to unpublish the episode',
+        'submit' => 'Unpublish',
+    ],
+    'delete_form' => [
+        'disclaimer' =>
+            "Deleting the episode will delete all media files, comments, video clips and soundbites associated with it.",
+        'understand' => 'I understand, I want to delete the episode',
+        'submit' => 'Delete',
+    ],
+    'embed' => [
+        'title' => 'Embeddable player',
+        'label' =>
+            'Pick a theme color, copy the embeddable player to clipboard, then paste it on your website.',
+        'clipboard_iframe' => 'Copy embeddable player to clipboard',
+        'clipboard_url' => 'Copy address to clipboard',
+        'dark' => 'Dark',
+        'dark-transparent' => 'Dark transparent',
+        'light' => 'Light',
+        'light-transparent' => 'Light transparent',
+    ],
+    'publication_status_banner' => [
+        'draft_mode' => 'draft mode',
+        'text' => '{publication_status, select,
+            published {This episode is not yet published.}
+            scheduled {This episode is scheduled for publication on {publication_date}.}
+            with_podcast {This episode will be published at the same time as the podcast.}
+            other {This episode is not yet published.}
+        }',
+        'preview' => 'Preview',
+    ],
+];
diff --git a/modules/Admin/Language/zh-Hant/EpisodeNavigation.php b/modules/Admin/Language/zh-Hant/EpisodeNavigation.php
new file mode 100644
index 00000000..1406e301
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/EpisodeNavigation.php
@@ -0,0 +1,23 @@
+<?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' => 'View episode page',
+    'dashboard' => 'Episode dashboard',
+    'episode-view' => 'Home',
+    'episode-edit' => 'Edit episode',
+    'episode-persons-manage' => 'Manage persons',
+    'embed-add' => 'Embeddable player',
+    'clips' => 'Clips',
+    'video-clips-list' => 'Video clips',
+    'video-clips-create' => 'New video clip',
+    'soundbites-list' => 'Soundbites',
+    'soundbites-create' => 'New soundbite',
+];
diff --git a/modules/Admin/Language/zh-Hant/Fediverse.php b/modules/Admin/Language/zh-Hant/Fediverse.php
new file mode 100644
index 00000000..0e4ca66d
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Fediverse.php
@@ -0,0 +1,32 @@
+<?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 [
+    'messages' => [
+        'actorNotFound' => 'The account could not be found!',
+        'blockActorSuccess' => '{actor} has been blocked!',
+        'unblockActorSuccess' => 'Actor has been unblocked!',
+        'blockDomainSuccess' => '{domain} has been blocked!',
+        'unblockDomainSuccess' => '{domain} has been unblocked!',
+    ],
+    'blocked_actors' => 'Blocked accounts',
+    'blocked_domains' => 'Blocked domains',
+    'block_lists_form' => [
+        'handle' => 'Account handle',
+        'handle_hint' => 'Input @username@domain account.',
+        'domain' => 'Domain name',
+        'submit' => 'Block!',
+    ],
+    'list' => [
+        'actor' => 'Account',
+        'domain' => 'Domain name',
+        'unblock' => 'Unblock',
+    ],
+];
diff --git a/modules/Admin/Language/zh-Hant/Home.php b/modules/Admin/Language/zh-Hant/Home.php
new file mode 100644
index 00000000..3ff4c04d
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Home.php
@@ -0,0 +1,14 @@
+<?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',
+];
diff --git a/modules/Admin/Language/zh-Hant/Install.php b/modules/Admin/Language/zh-Hant/Install.php
new file mode 100644
index 00000000..36e373a2
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Install.php
@@ -0,0 +1,61 @@
+<?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 [
+    '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 superadmin 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/Admin/Language/zh-Hant/Navigation.php b/modules/Admin/Language/zh-Hant/Navigation.php
new file mode 100644
index 00000000..f3ffb129
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Navigation.php
@@ -0,0 +1,44 @@
+<?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',
+    'not-authorized' => 'Not authorized',
+    'dashboard' => 'Dashboard',
+    'admin' => 'Home',
+    'podcasts' => 'Podcasts',
+    'podcast-list' => 'All podcasts',
+    'podcast-create' => 'New podcast',
+    'all-podcast-imports' => 'All Podcast imports',
+    'podcast-imports-add' => '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',
+    'admin-about' => 'About',
+    'account' => [
+        'my-account' => 'My account',
+        'change-password' => 'Change password',
+        'logout' => 'Logout',
+    ],
+];
diff --git a/modules/Admin/Language/zh-Hant/Notifications.php b/modules/Admin/Language/zh-Hant/Notifications.php
new file mode 100644
index 00000000..2b139d51
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Page.php b/modules/Admin/Language/zh-Hant/Page.php
new file mode 100644
index 00000000..b6f49de5
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Pager.php b/modules/Admin/Language/zh-Hant/Pager.php
new file mode 100644
index 00000000..e25ee638
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Person.php b/modules/Admin/Language/zh-Hant/Person.php
new file mode 100644
index 00000000..a652be9f
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Platforms.php b/modules/Admin/Language/zh-Hant/Platforms.php
new file mode 100644
index 00000000..e161181c
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Platforms.php
@@ -0,0 +1,43 @@
+<?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' => [
+        'podcasting' => 'Podcasting platforms',
+        'social' => 'Social networks',
+        'funding' => 'Funding links',
+    ],
+    'website' => 'Website',
+    'home_url' => 'Go to {platformName} website',
+    'register' => 'Register',
+    'submit_url' => 'Submit your podcast on {platformName}',
+    'your_link' => 'Your link',
+    'your_id' => [
+        'podcasting' => 'Your ID',
+        'social' => 'Your ID',
+        'funding' => 'Your CTA',
+    ],
+    'your_cta' => 'Your call to action',
+    '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/zh-Hant/Podcast.php b/modules/Admin/Language/zh-Hant/Podcast.php
new file mode 100644
index 00000000..d02b6cf4
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Podcast.php
@@ -0,0 +1,327 @@
+<?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',
+    'all_imports' => 'Podcast imports',
+    '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',
+    'monetization_other' => 'Other monetization',
+    '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.',
+        '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.',
+        'fediverse_section_title' => 'Fediverse identity',
+
+        '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. Episodes will be presented in numeric order.',
+        ],
+        'medium' => [
+            'label' => 'Medium',
+            'hint' => 'Medium as represented by podcast:medium tag in RSS. Changing this may change how players present your feed.',
+            'podcast' => 'Podcast',
+            'podcast_hint' => 'Describes a feed for a podcast show.',
+            'music' => 'Music',
+            'music_hint' => 'A feed of music organized into an "album" with each item a song within the album.',
+            'audiobook' => 'Audiobook',
+            'audiobook_hint' => 'Specific types of audio with one item per feed, or where items represent chapters within the book.',
+        ],
+        '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.',
+        'is_owner_email_removed_from_feed' => 'Remove the owner email from the public RSS feed',
+        'is_owner_email_removed_from_feed_hint' => 'You may need to temporarily unhide the email so that a directory can verify your podcast ownership.',
+        '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_link' => 'Visit your OP3 dashboard (external link)',
+        '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',
+        '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',
+        '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/zh-Hant/PodcastNavigation.php b/modules/Admin/Language/zh-Hant/PodcastNavigation.php
new file mode 100644
index 00000000..bb777707
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/PodcastNavigation.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 [
+    'go_to_page' => 'Go to podcast page',
+    'rss_feed' => 'RSS feed',
+    'dashboard' => 'Podcast dashboard',
+    'podcast-view' => 'Home',
+    'podcast-edit' => 'Edit podcast',
+    'podcast-persons-manage' => 'Manage persons',
+    'podcast-imports' => 'Podcast imports',
+    'podcast-imports-sync' => 'Sync feeds',
+    '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',
+    'monetization' => 'Monetization',
+    'subscription-list' => 'All subscriptions',
+    'subscription-create' => 'Add subscription',
+    'contributors' => 'Contributors',
+    'contributor-list' => 'All contributors',
+    'contributor-add' => 'Add contributor',
+    'broadcast' => 'Broadcast',
+    'platforms-podcasting' => 'Podcasting apps',
+    'platforms-social' => 'Social networks',
+    'platforms-funding' => 'Funding links',
+    'podcast-monetization-other' => 'Other',
+];
diff --git a/modules/Admin/Language/zh-Hant/Settings.php b/modules/Admin/Language/zh-Hant/Settings.php
new file mode 100644
index 00000000..4a70dcba
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Soundbite.php b/modules/Admin/Language/zh-Hant/Soundbite.php
new file mode 100644
index 00000000..a3f828fe
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/zh-Hant/Validation.php b/modules/Admin/Language/zh-Hant/Validation.php
new file mode 100644
index 00000000..f76c3163
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/Validation.php
@@ -0,0 +1,17 @@
+<?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.',
+    'is_json' => '{field} contains invalid JSON.',
+];
diff --git a/modules/Admin/Language/zh-Hant/VideoClip.php b/modules/Admin/Language/zh-Hant/VideoClip.php
new file mode 100644
index 00000000..638de697
--- /dev/null
+++ b/modules/Admin/Language/zh-Hant/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/Auth/Language/eu/Auth.php b/modules/Auth/Language/eu/Auth.php
new file mode 100644
index 00000000..725b760b
--- /dev/null
+++ b/modules/Auth/Language/eu/Auth.php
@@ -0,0 +1,93 @@
+<?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',
+
+    '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/eu/Contributor.php b/modules/Auth/Language/eu/Contributor.php
new file mode 100644
index 00000000..c70badc0
--- /dev/null
+++ b/modules/Auth/Language/eu/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/eu/MyAccount.php b/modules/Auth/Language/eu/MyAccount.php
new file mode 100644
index 00000000..6ebbb30e
--- /dev/null
+++ b/modules/Auth/Language/eu/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/eu/User.php b/modules/Auth/Language/eu/User.php
new file mode 100644
index 00000000..32ec560c
--- /dev/null
+++ b/modules/Auth/Language/eu/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/Auth/Language/zh-Hant/Auth.php b/modules/Auth/Language/zh-Hant/Auth.php
new file mode 100644
index 00000000..725b760b
--- /dev/null
+++ b/modules/Auth/Language/zh-Hant/Auth.php
@@ -0,0 +1,93 @@
+<?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',
+
+    '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/zh-Hant/Contributor.php b/modules/Auth/Language/zh-Hant/Contributor.php
new file mode 100644
index 00000000..c70badc0
--- /dev/null
+++ b/modules/Auth/Language/zh-Hant/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/zh-Hant/MyAccount.php b/modules/Auth/Language/zh-Hant/MyAccount.php
new file mode 100644
index 00000000..6ebbb30e
--- /dev/null
+++ b/modules/Auth/Language/zh-Hant/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/zh-Hant/User.php b/modules/Auth/Language/zh-Hant/User.php
new file mode 100644
index 00000000..32ec560c
--- /dev/null
+++ b/modules/Auth/Language/zh-Hant/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/eu/Install.php b/modules/Install/Language/eu/Install.php
new file mode 100644
index 00000000..45d26085
--- /dev/null
+++ b/modules/Install/Language/eu/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/Install/Language/zh-Hant/Install.php b/modules/Install/Language/zh-Hant/Install.php
new file mode 100644
index 00000000..45d26085
--- /dev/null
+++ b/modules/Install/Language/zh-Hant/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/PodcastImport/Language/de/PodcastImport.php b/modules/PodcastImport/Language/de/PodcastImport.php
index 8bf494d3..0037a0c0 100644
--- a/modules/PodcastImport/Language/de/PodcastImport.php
+++ b/modules/PodcastImport/Language/de/PodcastImport.php
@@ -12,7 +12,7 @@ return [
     'banner' => [
         'disclaimer' => 'Importing',
         'text' => '{podcastTitle} is currently being imported.',
-        'cta' => 'See import status',
+        'cta' => 'Importstatus anzeigen',
     ],
     'old_podcast_section_title' => 'The podcast to import',
     'old_podcast_legal_disclaimer_title' => 'Legal disclaimer',
@@ -27,15 +27,15 @@ return [
     'queue' => [
         'status' => [
             'label' => 'Status',
-            'queued' => 'queued',
+            'queued' => 'in Warteschlangen',
             'queued_hint' => 'Import task is awaiting to be processed.',
-            'canceled' => 'canceled',
+            'canceled' => 'abgebrochen',
             'canceled_hint' => 'Import task was canceled.',
-            'running' => 'running',
+            'running' => 'läuft',
             'running_hint' => 'Import task is being processed.',
-            'failed' => 'failed',
+            'failed' => 'fehlgeschlagen',
             'failed_hint' => 'Import task could not complete: script failure.',
-            'passed' => 'passed',
+            'passed' => 'bestanden',
             'passed_hint' => 'Import task was completed successfully!',
         ],
         'feed' => 'Feed',
@@ -43,16 +43,16 @@ return [
         'imported_episodes' => 'Imported episodes',
         'imported_episodes_hint' => '{newlyImportedCount} newly imported, {alreadyImportedCount} already imported.',
         'actions' => [
-            'cancel' => 'Cancel',
-            'retry' => 'Retry',
-            'delete' => 'Delete',
+            'cancel' => 'Abbrechen',
+            'retry' => 'Erneut versuchen',
+            'delete' => 'Löschen',
         ],
     ],
     'syncForm' => [
-        'title' => 'Synchronize feeds',
+        'title' => 'Feeds synchronisieren',
         'feed_url' => 'Feed URL',
         'feed_url_hint' => 'The feed URL you want to synchronize with the current podcast.',
-        'submit' => 'Add to queue',
+        'submit' => 'Zur Warteschlange hinzufügen',
     ],
     'messages' => [
         'canceled' => 'Import task has been successfully canceled!',
diff --git a/modules/PodcastImport/Language/eu/PodcastImport.php b/modules/PodcastImport/Language/eu/PodcastImport.php
new file mode 100644
index 00000000..8bf494d3
--- /dev/null
+++ b/modules/PodcastImport/Language/eu/PodcastImport.php
@@ -0,0 +1,66 @@
+<?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 [
+    'banner' => [
+        'disclaimer' => 'Importing',
+        'text' => '{podcastTitle} is currently being imported.',
+        'cta' => 'See import status',
+    ],
+    'old_podcast_section_title' => 'The podcast to import',
+    'old_podcast_legal_disclaimer_title' => 'Legal disclaimer',
+    'old_podcast_legal_disclaimer' =>
+        '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',
+    'lock_import' =>
+        'This feed is protected. You cannot import it. If you are the owner, unlock it on the origin platform.',
+    'submit' => 'Add import to queue',
+    'queue' => [
+        'status' => [
+            'label' => 'Status',
+            'queued' => 'queued',
+            'queued_hint' => 'Import task is awaiting to be processed.',
+            'canceled' => 'canceled',
+            'canceled_hint' => 'Import task was canceled.',
+            'running' => 'running',
+            'running_hint' => 'Import task is being processed.',
+            'failed' => 'failed',
+            'failed_hint' => 'Import task could not complete: script failure.',
+            'passed' => 'passed',
+            'passed_hint' => 'Import task was completed successfully!',
+        ],
+        'feed' => 'Feed',
+        'duration' => 'Import duration',
+        'imported_episodes' => 'Imported episodes',
+        'imported_episodes_hint' => '{newlyImportedCount} newly imported, {alreadyImportedCount} already imported.',
+        'actions' => [
+            'cancel' => 'Cancel',
+            'retry' => 'Retry',
+            'delete' => 'Delete',
+        ],
+    ],
+    'syncForm' => [
+        'title' => 'Synchronize feeds',
+        'feed_url' => 'Feed URL',
+        'feed_url_hint' => 'The feed URL you want to synchronize with the current podcast.',
+        'submit' => 'Add to queue',
+    ],
+    'messages' => [
+        'canceled' => 'Import task has been successfully canceled!',
+        'notRunning' => 'Cannot cancel Import Task as it is not running.',
+        'alreadyRunning' => 'Import Task is already running. You may cancel it before retrying.',
+        'retried' => 'Import task has been queued, it will be retried shortly!',
+        'deleted' => 'Import task has been successfully deleted!',
+        'importTaskQueued' => 'An new task has been queued, import will start shortly!',
+        'syncTaskQueued' => 'A new import task has been queued, synchronization will start shortly!',
+    ],
+];
diff --git a/modules/PodcastImport/Language/zh-Hant/PodcastImport.php b/modules/PodcastImport/Language/zh-Hant/PodcastImport.php
new file mode 100644
index 00000000..8bf494d3
--- /dev/null
+++ b/modules/PodcastImport/Language/zh-Hant/PodcastImport.php
@@ -0,0 +1,66 @@
+<?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 [
+    'banner' => [
+        'disclaimer' => 'Importing',
+        'text' => '{podcastTitle} is currently being imported.',
+        'cta' => 'See import status',
+    ],
+    'old_podcast_section_title' => 'The podcast to import',
+    'old_podcast_legal_disclaimer_title' => 'Legal disclaimer',
+    'old_podcast_legal_disclaimer' =>
+        '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',
+    'lock_import' =>
+        'This feed is protected. You cannot import it. If you are the owner, unlock it on the origin platform.',
+    'submit' => 'Add import to queue',
+    'queue' => [
+        'status' => [
+            'label' => 'Status',
+            'queued' => 'queued',
+            'queued_hint' => 'Import task is awaiting to be processed.',
+            'canceled' => 'canceled',
+            'canceled_hint' => 'Import task was canceled.',
+            'running' => 'running',
+            'running_hint' => 'Import task is being processed.',
+            'failed' => 'failed',
+            'failed_hint' => 'Import task could not complete: script failure.',
+            'passed' => 'passed',
+            'passed_hint' => 'Import task was completed successfully!',
+        ],
+        'feed' => 'Feed',
+        'duration' => 'Import duration',
+        'imported_episodes' => 'Imported episodes',
+        'imported_episodes_hint' => '{newlyImportedCount} newly imported, {alreadyImportedCount} already imported.',
+        'actions' => [
+            'cancel' => 'Cancel',
+            'retry' => 'Retry',
+            'delete' => 'Delete',
+        ],
+    ],
+    'syncForm' => [
+        'title' => 'Synchronize feeds',
+        'feed_url' => 'Feed URL',
+        'feed_url_hint' => 'The feed URL you want to synchronize with the current podcast.',
+        'submit' => 'Add to queue',
+    ],
+    'messages' => [
+        'canceled' => 'Import task has been successfully canceled!',
+        'notRunning' => 'Cannot cancel Import Task as it is not running.',
+        'alreadyRunning' => 'Import Task is already running. You may cancel it before retrying.',
+        'retried' => 'Import task has been queued, it will be retried shortly!',
+        'deleted' => 'Import task has been successfully deleted!',
+        'importTaskQueued' => 'An new task has been queued, import will start shortly!',
+        'syncTaskQueued' => 'A new import task has been queued, synchronization will start shortly!',
+    ],
+];
diff --git a/modules/PremiumPodcasts/Language/de/Subscription.php b/modules/PremiumPodcasts/Language/de/Subscription.php
index e57db5a2..67b91013 100644
--- a/modules/PremiumPodcasts/Language/de/Subscription.php
+++ b/modules/PremiumPodcasts/Language/de/Subscription.php
@@ -34,7 +34,7 @@ return [
         'email' => 'E-Mail',
         'expiration_date' => 'Ablaufdatum',
         'expiration_date_hint' => 'Das Datum und die Uhrzeit, zu der das Abonnement abläuft. Leer lassen für ein unbegrenztes Abonnement.',
-        'submit_create' => 'Create subscription',
+        'submit_create' => 'Abonnement einrichten',
         'submit_edit' => 'Abonnement bearbeiten',
     ],
     'form_link_add' => [
diff --git a/modules/PremiumPodcasts/Language/eu/PremiumPodcasts.php b/modules/PremiumPodcasts/Language/eu/PremiumPodcasts.php
new file mode 100644
index 00000000..18c0dd4e
--- /dev/null
+++ b/modules/PremiumPodcasts/Language/eu/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/eu/Subscription.php b/modules/PremiumPodcasts/Language/eu/Subscription.php
new file mode 100644
index 00000000..e83f0cb2
--- /dev/null
+++ b/modules/PremiumPodcasts/Language/eu/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_create' => 'Create 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}',
+    ],
+];
diff --git a/modules/PremiumPodcasts/Language/zh-Hant/PremiumPodcasts.php b/modules/PremiumPodcasts/Language/zh-Hant/PremiumPodcasts.php
new file mode 100644
index 00000000..18c0dd4e
--- /dev/null
+++ b/modules/PremiumPodcasts/Language/zh-Hant/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/zh-Hant/Subscription.php b/modules/PremiumPodcasts/Language/zh-Hant/Subscription.php
new file mode 100644
index 00000000..e83f0cb2
--- /dev/null
+++ b/modules/PremiumPodcasts/Language/zh-Hant/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_create' => 'Create 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}',
+    ],
+];