diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index e35a953f99a2337116e5bfd5fe8729fce0bb7336..b3facd646ab90efbadcb19e3547d81947e721f51 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -445,6 +445,7 @@ This hierarchical structure is made of several parts:
     - ``Artist``
     - ``Home``
     - ``Login``
+    - ``Library``
     - ``Moderation``
     - ``Player``
     - ``Playlist``
@@ -461,6 +462,7 @@ This hierarchical structure is made of several parts:
     - ``Button``
     - ``Card``
     - ``Dropdown``
+    - ``Error message``
     - ``Form``
     - ``Header``
     - ``Help text``
diff --git a/front/src/views/content/remote/Card.vue b/front/src/views/content/remote/Card.vue
index c9d7ad1a4b6c63f9b12a05bcaa47db4ea5153546..ce5ab53eef0761889d04a04506515ddbf3f90ed9 100644
--- a/front/src/views/content/remote/Card.vue
+++ b/front/src/views/content/remote/Card.vue
@@ -24,44 +24,44 @@
       </div>
       <div class="meta">
         <i class="music icon"></i>
-        <translate :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
+        <translate :translate-context="'Content/Library/Card.List item'" :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
       </div>
       <div v-if="displayScan && latestScan" class="meta">
         <template v-if="latestScan.status === 'pending'">
           <i class="hourglass icon"></i>
-          <translate>Scan waiting</translate>
+          <translate :translate-context="'Content/Library/Card.List item'">Scan pending</translate>
         </template>
         <template v-if="latestScan.status === 'scanning'">
           <i class="loading spinner icon"></i>
-          <translate :translate-params="{progress: scanProgress}">Scanning… (%{ progress }%)</translate>
+          <translate :translate-context="'Content/Library/Card.List item'" :translate-params="{progress: scanProgress}">Scanning… (%{ progress }%)</translate>
         </template>
         <template v-else-if="latestScan.status === 'errored'">
           <i class="red download icon"></i>
-          <translate>Problem during scanning</translate>
+          <translate :translate-context="'Content/Library/Card.List item'">Problem during scanning</translate>
         </template>
         <template v-else-if="latestScan.status === 'finished' && latestScan.errored_files === 0">
           <i class="green download icon"></i>
-          <translate>Scanned</translate>
+          <translate :translate-context="'Content/Library/Card.List item'">Scanned</translate>
         </template>
         <template v-else-if="latestScan.status === 'finished' && latestScan.errored_files > 0">
           <i class="yellow download icon"></i>
-          <translate>Scanned with errors</translate>
+          <translate :translate-context="'Content/Library/Card.List item'">Scanned with errors</translate>
         </template>
         <span class="link right floated" @click="showScan = !showScan">
-          <translate>Details</translate>
+          <translate :translate-context="'Content/Library/Card.Link'">Details</translate>
           <i v-if="showScan" class="angle down icon" />
           <i v-else class="angle right icon" />
         </span>
         <div v-if="showScan">
           <template v-if="latestScan.modification_date">
-            <translate>Last update:</translate><human-date :date="latestScan.modification_date" /><br />
+            <translate :translate-context="'Content/Library/Card.List item/Noun'">Last update:</translate><human-date :date="latestScan.modification_date" /><br />
           </template>
-          <translate>Failed tracks:</translate> {{ latestScan.errored_files }}
+          <translate :translate-context="'Content/Library/Card.List item/Noun'">Failed tracks:</translate> {{ latestScan.errored_files }}
         </div>
       </div>
       <div v-if="displayScan && canLaunchScan" class="clearfix">
         <span class="right floated link" @click="launchScan">
-          <translate>Scan now</translate> <i class="paper plane icon" />
+          <translate :translate-context="'Content/Library/Card.Button.Label/Verb'">Scan now</translate> <i class="paper plane icon" />
         </span>
       </div>
     </div>
@@ -71,7 +71,7 @@
     <div v-if="displayCopyFid" class="extra content">
       <div class="ui form">
         <div class="field">
-          <label><translate>Sharing link</translate></label>
+          <label><translate :translate-context="'Content/Library/Title'">Sharing link</translate></label>
           <copy-input :button-classes="'basic'" :value="library.fid" />
         </div>
       </div>
@@ -81,29 +81,29 @@
         v-if="!library.follow"
         @click="follow()"
         :class="['ui', 'green', {'loading': isLoadingFollow}, 'button']">
-        <translate>Follow</translate>
+        <translate :translate-context="'Content/Library/Card.Button.Label/Verb'">Follow</translate>
       </button>
       <button
         v-else-if="!library.follow.approved"
         class="ui disabled button"><i class="hourglass icon"></i>
-        <translate>Follow request pending approval</translate>
+        <translate :translate-context="'Content/Library/Card.Paragraph'">Follow request pending approval</translate>
       </button>
       <button
         v-else-if="!library.follow.approved"
         class="ui disabled button"><i class="check icon"></i>
-        <translate>Following</translate>
+        <translate :translate-context="'Content/Library/Card.Paragraph'">Following</translate>
       </button>
       <dangerous-button
         v-else-if="library.follow.approved"
         color=""
         :class="['ui', 'button']"
         :action="unfollow">
-        <translate>Unfollow</translate>
-        <p slot="modal-header"><translate>Unfollow this library?</translate></p>
+        <translate :translate-context="'Content/Library/Card.Button.Label/Verb'">Unfollow</translate>
+        <p slot="modal-header"><translate :translate-context="'Popup/Library/Title'">Unfollow this library?</translate></p>
         <div slot="modal-content">
-          <p><translate>By unfollowing this library, you loose access to its content.</translate></p>
+          <p><translate :translate-context="'Popup/Library/Paragraph'">By unfollowing this library, you loose access to its content.</translate></p>
         </div>
-        <p slot="modal-confirm"><translate>Unfollow</translate></p>
+        <p slot="modal-confirm"><translate :translate-context="'Popup/Library/Button.Label'">Unfollow</translate></p>
       </dangerous-button>
     </div>
   </div>
@@ -128,8 +128,8 @@ export default {
   },
   computed: {
     labels () {
-      let me = this.$gettext('This library is private and your approval from its owner is needed to access its content')
-      let everyone = this.$gettext('This library is public and you can access its content freely')
+      let me = this.$pgettext('Content/Library/Card.Help text', 'This library is private and your approval from its owner is needed to access its content')
+      let everyone = this.$pgettext('Content/Library/Card.Help text', 'This library is public and you can access its content freely')
 
       return {
         tooltips: {
@@ -162,8 +162,8 @@ export default {
   methods: {
     launchScan () {
       let self = this
-      let successMsg = this.$gettext('Scan launched')
-      let skippedMsg = this.$gettext('Scan skipped (previous scan is too recent)')
+      let successMsg = this.$pgettext('Content/Library/Message', 'Scan launched')
+      let skippedMsg = this.$pgettext('Content/Library/Message', 'Scan skipped (previous scan is too recent)')
       axios.post(`federation/libraries/${this.library.uuid}/scan/`).then((response) => {
         let msg
         if (response.data.status == 'skipped') {
diff --git a/front/src/views/content/remote/Home.vue b/front/src/views/content/remote/Home.vue
index 007fbadcaa51a84a54c44d6d53cef852a3538733..4e813a5ba14a746fe92af03d62f21064c33b662c 100644
--- a/front/src/views/content/remote/Home.vue
+++ b/front/src/views/content/remote/Home.vue
@@ -1,19 +1,19 @@
 <template>
   <div class="ui vertical aligned stripe segment">
     <div v-if="isLoading" :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
-      <div class="ui text loader"><translate>Loading remote libraries…</translate></div>
+      <div class="ui text loader"><translate :translate-context="'Content/Library/Paragraph'">Loading remote libraries…</translate></div>
     </div>
     <div v-else class="ui text container">
-      <h1 class="ui header"><translate>Remote libraries</translate></h1>
-      <p><translate>Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access.</translate></p>
+      <h1 class="ui header"><translate :translate-context="'Content/Library/Title/Noun'">Remote libraries</translate></h1>
+      <p><translate :translate-context="'Content/Library/Paragraph'">Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access.</translate></p>
       <scan-form @scanned="scanResult = $event"></scan-form>
       <div class="ui hidden divider"></div>
       <div v-if="scanResult && scanResult.results.length > 0" class="ui two cards">
         <library-card :library="library" v-for="library in scanResult.results" :key="library.fid" />
       </div>
       <template v-if="existingFollows && existingFollows.count > 0">
-        <h2><translate>Known libraries</translate></h2>
-        <i @click="fetch()" :class="['ui', 'circular', 'refresh', 'icon']" /> <translate>Refresh</translate>
+        <h2><translate :translate-context="'Content/Library/Title'">Known libraries</translate></h2>
+        <i @click="fetch()" :class="['ui', 'circular', 'refresh', 'icon']" /> <translate :translate-context="'Content/Library/Button.Label'">Refresh</translate>
         <div class="ui hidden divider"></div>
         <div class="ui two cards">
           <library-card
diff --git a/front/src/views/content/remote/ScanForm.vue b/front/src/views/content/remote/ScanForm.vue
index dc1b2b78b730a98ed8a7940e69c135a863390389..31bc803184120f04e493da9176d7275929fa177f 100644
--- a/front/src/views/content/remote/ScanForm.vue
+++ b/front/src/views/content/remote/ScanForm.vue
@@ -1,13 +1,13 @@
 <template>
   <form class="ui form" @submit.prevent="scan">
     <div v-if="errors.length > 0" class="ui negative message">
-      <div class="header"><translate>Could not fetch remote library</translate></div>
+      <div class="header"><translate :translate-context="'Content/Library/Error message.Title'">Could not fetch remote library</translate></div>
       <ul class="list">
         <li v-for="error in errors">{{ error }}</li>
       </ul>
     </div>
     <div class="ui field">
-      <label><translate>Search a remote library</translate></label>
+      <label><translate :translate-context="'Content/Library/Input.Label/Verb'">Search a remote library</translate></label>
       <div :class="['ui', 'action', {loading: isLoading}, 'input']">
         <input name="url" v-model="query" :placeholder="labels.placeholder" type="url">
         <button type="submit" class="ui icon button">
@@ -47,7 +47,7 @@ export default {
   },
   computed: {
     labels () {
-      let placeholder = this.$gettext('Enter a library URL')
+      let placeholder = this.$pgettext('Content/Library/Input.Placeholder', 'Enter a library URL')
       return {
         placeholder
       }