diff --git a/front/src/components/Queue.vue b/front/src/components/Queue.vue
index ae4a447fe6d763ced97b2a340ad410e7080a7184..5b92d76d93eb64dafb6230077480c8e8a51ab9c7 100644
--- a/front/src/components/Queue.vue
+++ b/front/src/components/Queue.vue
@@ -72,7 +72,7 @@
                   </div>
                   <div class="progress">
                     <template v-if="!isLoadingAudio">
-                      <span role="button" class="left floated timer start" @click="setCurrentTime(0)">{{currentTimeFormatted}}</span>
+                      <a href="" :aria-label="labels.restart" class="left floated timer discrete start" @click.prevent="setCurrentTime(0)">{{currentTimeFormatted}}</a>
                       <span class="right floated timer total">{{durationFormatted}}</span>
                     </template>
                     <template v-else>
@@ -272,7 +272,8 @@ export default {
       return {
         queue: this.$pgettext('*/*/*', 'Queue'),
         duration: this.$pgettext('*/*/*', 'Duration'),
-        addArtistContentFilter: this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Hide content from this artist…')
+        addArtistContentFilter: this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Hide content from this artist…'),
+        restart: this.$pgettext('*/*/*', 'Restart track'),
       }
     },
     timeLeft () {
diff --git a/front/src/components/Sidebar.vue b/front/src/components/Sidebar.vue
index 2a2a6e7a51b6b1239f69fc4b9e53e8222a7480f6..6ec684f6eb0b851f020664c766b8e3a90eac4ca5 100644
--- a/front/src/components/Sidebar.vue
+++ b/front/src/components/Sidebar.vue
@@ -90,10 +90,10 @@
       </template>
       <div class="item collapse-button-wrapper">
 
-        <span
+        <button
           @click="isCollapsed = !isCollapsed"
           :class="['ui', 'basic', 'big', {'vibrant': !isCollapsed}, 'inverted icon', 'collapse', 'button']">
-            <i class="sidebar icon"></i></span>
+            <i class="sidebar icon"></i></button>
       </div>
     </nav>
   </header>
@@ -115,7 +115,7 @@
     <section :class="['ui', 'bottom', 'attached', {active: selectedTab === 'library'}, 'tab']" :aria-label="labels.mainMenu">
       <nav class="ui vertical large fluid inverted menu" role="navigation" :aria-label="labels.mainMenu">
         <div :class="[{collapsed: !exploreExpanded}, 'collaspable item']">
-          <h2 class="header" @click="exploreExpanded = true" tabindex="0" @focus="exploreExpanded = true">
+          <h2 class="header" role="button" @click="exploreExpanded = true" tabindex="0" @focus="exploreExpanded = true">
             <translate translate-context="*/*/*/Verb">Explore</translate>
             <i class="angle right icon" v-if="!exploreExpanded"></i>
           </h2>
@@ -128,7 +128,7 @@
           </div>
         </div>
         <div :class="[{collapsed: !myLibraryExpanded}, 'collaspable item']" v-if="$store.state.auth.authenticated">
-          <h3 class="header" @click="myLibraryExpanded = true" tabindex="0" @focus="myLibraryExpanded = true">
+          <h3 class="header" role="button" @click="myLibraryExpanded = true" tabindex="0" @focus="myLibraryExpanded = true">
             <translate translate-context="*/*/*/Noun">My Library</translate>
             <i class="angle right icon" v-if="!myLibraryExpanded"></i>
           </h3>
diff --git a/front/src/components/admin/SignupFormBuilder.vue b/front/src/components/admin/SignupFormBuilder.vue
index ab6738390820d5c50308f21840dbc9f04a3fd581..3724b883ecd43b3ff5350786feb970b5ce027875 100644
--- a/front/src/components/admin/SignupFormBuilder.vue
+++ b/front/src/components/admin/SignupFormBuilder.vue
@@ -80,15 +80,15 @@
               <td>
                 <i
                   :disabled="idx === 0"
-                  @click="move(idx, -1)" rel="button"
+                  @click="move(idx, -1)" role="button"
                   :title="labels.up"
                   :class="['up', 'arrow', {disabled: idx === 0}, 'icon']"></i>
                 <i
                   :disabled="idx >= local.fields.length - 1"
-                  @click="move(idx, 1)" rel="button"
+                  @click="move(idx, 1)" role="button"
                   :title="labels.down"
                   :class="['down', 'arrow', {disabled: idx >= local.fields.length - 1}, 'icon']"></i>
-                <i @click="remove(idx)" rel="button" :title="labels.delete" class="x icon"></i>
+                <i @click="remove(idx)" role="button" :title="labels.delete" class="x icon"></i>
               </td>
             </tr>
           </tbody>
diff --git a/front/src/components/common/ActionTable.vue b/front/src/components/common/ActionTable.vue
index bb6685ca376f9e34d5ddaa318dcfc60af497bd7d..38a6d23d02b39b0e023f25d5be8f265b2dd3164d 100644
--- a/front/src/components/common/ActionTable.vue
+++ b/front/src/components/common/ActionTable.vue
@@ -48,13 +48,13 @@
                     </p>
                     <div :aria-label="labels.performAction" slot="modal-confirm"><translate translate-context="Modal/*/Button.Label/Short, Verb">Launch</translate></div>
                   </dangerous-button>
-                  <div
+                  <button
                     v-else
                     @click="launchAction"
                     :disabled="checked.length === 0"
                     :aria-label="labels.performAction"
                     :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']">
-                    <translate translate-context="Content/*/Button.Label/Short, Verb">Go</translate></div>
+                    <translate translate-context="Content/*/Button.Label/Short, Verb">Go</translate></button>
                 </div>
                 <div class="count field">
                   <translate translate-context="Content/*/Paragraph"
@@ -76,7 +76,7 @@
                     %{ count } on %{ total } selected
                   </translate>
                   <template v-if="currentAction.allowAll && checkable.length > 0 && checkable.length === checked.length">
-                    <a @click="selectAll = true" v-if="!selectAll">
+                    <a @click.prevent="selectAll = true" v-if="!selectAll" href="">
                       <translate translate-context="Content/*/Link/Verb"
                         key="3"
                         :translate-n="objectsData.count"
@@ -85,7 +85,7 @@
                         Select all %{ total } elements
                       </translate>
                     </a>
-                    <a @click="selectAll = false" v-else>
+                    <a @click.prevent="selectAll = false" v-else href="">
                       <translate translate-context="Content/*/Link/Verb" key="4">Select only current page</translate>
                     </a>
                   </template>
diff --git a/front/src/components/common/RenderedDescription.vue b/front/src/components/common/RenderedDescription.vue
index fa40ab169efd357b273d5e66e3539f95412481a3..b7db84d644c52d04f72dda7551f57e3c207d5e2b 100644
--- a/front/src/components/common/RenderedDescription.vue
+++ b/front/src/components/common/RenderedDescription.vue
@@ -4,10 +4,10 @@
       <div v-html="html"></div>
       <template v-if="isTruncated">
         <div class="ui small hidden divider"></div>
-        <a @click.stop.prevent="showMore = true" v-if="showMore === false">
+        <a href="" @click.stop.prevent="showMore = true" v-if="showMore === false">
           <translate translate-context="*/*/Button,Label">Show more</translate>
         </a>
-        <a @click.stop.prevent="showMore = false" v-else="showMore === true">
+        <a href="" @click.stop.prevent="showMore = false" v-else="showMore === true">
           <translate translate-context="*/*/Button,Label">Show less</translate>
         </a>
 
diff --git a/front/src/components/library/FileUpload.vue b/front/src/components/library/FileUpload.vue
index 8bcf55bbe4007ab0fc80c64f10e3cbfee82893ea..7a0c9e30ebccb5a823b2cef6fcdaa431f5dddf5e 100644
--- a/front/src/components/library/FileUpload.vue
+++ b/front/src/components/library/FileUpload.vue
@@ -1,8 +1,8 @@
   <template>
   <div class="component-file-upload">
     <div class="ui top attached tabular menu">
-      <a :class="['item', {active: currentTab === 'summary'}]" @click="currentTab = 'summary'"><translate translate-context="Content/Library/Tab.Title/Short">Summary</translate></a>
-      <a :class="['item', {active: currentTab === 'uploads'}]" @click="currentTab = 'uploads'">
+      <a href="" :class="['item', {active: currentTab === 'summary'}]" @click.prevent="currentTab = 'summary'"><translate translate-context="Content/Library/Tab.Title/Short">Summary</translate></a>
+      <a href="" :class="['item', {active: currentTab === 'uploads'}]" @click.prevent="currentTab = 'uploads'">
         <translate translate-context="Content/Library/Tab.Title/Short">Uploading</translate>
         <div v-if="files.length === 0" class="ui label">
           0
@@ -14,7 +14,7 @@
           {{ uploadedFilesCount + erroredFilesCount }}/{{ files.length }}
         </div>
       </a>
-      <a :class="['item', {active: currentTab === 'processing'}]" @click="currentTab = 'processing'">
+      <a href="" :class="['item', {active: currentTab === 'processing'}]" @click.prevent="currentTab = 'processing'">
         <translate translate-context="Content/Library/Tab.Title/Short">Processing</translate>
         <div v-if="processableFiles === 0" class="ui label">
           0
diff --git a/front/src/components/library/radios/Filter.vue b/front/src/components/library/radios/Filter.vue
index 2a9c86b0588299243b6fac4d2922360cf935509a..a5f910083139828c5b69e3c0bd39455008dd1752 100644
--- a/front/src/components/library/radios/Filter.vue
+++ b/front/src/components/library/radios/Filter.vue
@@ -35,12 +35,13 @@
       </div>
     </td>
     <td>
-      <span
-        @click="showCandidadesModal = !showCandidadesModal"
+      <a
+        href=""
+        @click.prevent="showCandidadesModal = !showCandidadesModal"
         v-if="checkResult"
         :class="['ui', {'success': checkResult.candidates.count > 10}, 'label']">
         {{ checkResult.candidates.count }} tracks matching filter
-      </span>
+      </a>
       <modal v-if="checkResult" :show.sync="showCandidadesModal">
         <h4 class="header">
           <translate translate-context="Popup/Radio/Title/Noun">Tracks matching filter</translate>
diff --git a/front/src/components/manage/ChannelsTable.vue b/front/src/components/manage/ChannelsTable.vue
index 04d6a9fdd25bba93058ca9266111648f3cc8fb76..337ecfbfefddd0853b77bdbce1b98b86b45b700d 100644
--- a/front/src/components/manage/ChannelsTable.vue
+++ b/front/src/components/manage/ChannelsTable.vue
@@ -62,7 +62,7 @@
               <i class="wrench icon"></i>
               <span class="visually-hidden">{{ labels.openModeration }}</span>
             </router-link>
-            <span role="button" class="discrete link" @click="addSearchToken('account', scope.obj.attributed_to.full_username)">{{ scope.obj.attributed_to.preferred_username }}</span>
+            <a href="" class="discrete link" @click.prevent="addSearchToken('account', scope.obj.attributed_to.full_username)">{{ scope.obj.attributed_to.preferred_username }}</a>
           </td>
           <td>
             <template v-if="!scope.obj.is_local">
@@ -70,12 +70,12 @@
                 <i class="wrench icon"></i>
                 <span class="visually-hidden">{{ labels.openModeration }}</span>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.attributed_to.domain)">{{ scope.obj.attributed_to.domain }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('domain', scope.obj.attributed_to.domain)">{{ scope.obj.attributed_to.domain }}</a>
             </template>
-            <span role="button" v-else class="ui tiny accent icon link label" @click="addSearchToken('domain', scope.obj.attributed_to.domain)">
+            <a href="" v-else class="ui tiny accent icon link label" @click.prevent="addSearchToken('domain', scope.obj.attributed_to.domain)">
               <i class="home icon"></i>
               <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
-            </span>
+            </a>
           </td>
           <td>
             {{ scope.obj.artist.albums_count }}
diff --git a/front/src/components/manage/library/AlbumsTable.vue b/front/src/components/manage/library/AlbumsTable.vue
index cd71fc02e221bd43623b0cda4b59d256cee09b17..3bff5035296438cf5133123c7b49b3eb69eb50cb 100644
--- a/front/src/components/manage/library/AlbumsTable.vue
+++ b/front/src/components/manage/library/AlbumsTable.vue
@@ -53,7 +53,7 @@
               <i class="wrench icon"></i>
               <span class="visually-hidden">{{ labels.openModeration }}</span>
             </router-link>
-            <span role="button" class="discrete link" @click="addSearchToken('artist', scope.obj.artist.name)" :title="scope.obj.artist.name">{{ scope.obj.artist.name }}</span>
+            <a href="" class="discrete link" @click.prevent="addSearchToken('artist', scope.obj.artist.name)" :title="scope.obj.artist.name">{{ scope.obj.artist.name }}</a>
           </td>
           <td>
             <template v-if="!scope.obj.is_local">
@@ -61,12 +61,12 @@
                 <i class="wrench icon"></i>
                 <span class="visually-hidden">{{ labels.openModeration }}</span>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)">{{ scope.obj.domain }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('domain', scope.obj.domain)">{{ scope.obj.domain }}</a>
             </template>
-            <span role="button" v-else class="ui tiny accent icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+            <a href="" v-else class="ui tiny accent icon link label" @click.prevent="addSearchToken('domain', scope.obj.domain)">
               <i class="home icon"></i>
               <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
-            </span>
+            </a>
           </td>
           <td>
             {{ scope.obj.tracks_count }}
diff --git a/front/src/components/manage/library/ArtistsTable.vue b/front/src/components/manage/library/ArtistsTable.vue
index 5babb6f53d7f798d5559d7177eeb08065edd1892..454496d35303c3a41db4fa16f96c0c046658e606 100644
--- a/front/src/components/manage/library/ArtistsTable.vue
+++ b/front/src/components/manage/library/ArtistsTable.vue
@@ -63,12 +63,12 @@
               <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
                 <i class="wrench icon"></i>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</a>
             </template>
-            <span role="button" v-else class="ui tiny accent icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+            <a href="" v-else class="ui tiny accent icon link label" @click.prevent="addSearchToken('domain', scope.obj.domain)">
               <i class="home icon"></i>
               <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
-            </span>
+            </a>
           </td>
           <td>
             {{ scope.obj.albums_count }}
diff --git a/front/src/components/manage/library/LibrariesTable.vue b/front/src/components/manage/library/LibrariesTable.vue
index 3cfb74739a38aa7f839a1a17f9c33c7696b79042..b5bb8b9b8051c91676d753d0d6e2579f6d6b9c03 100644
--- a/front/src/components/manage/library/LibrariesTable.vue
+++ b/front/src/components/manage/library/LibrariesTable.vue
@@ -62,28 +62,28 @@
             <router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.actor.full_username }}">
               <i class="wrench icon"></i>
             </router-link>
-            <span role="button" class="discrete link" @click="addSearchToken('account', scope.obj.actor.full_username)" :title="scope.obj.actor.full_username">{{ scope.obj.actor.preferred_username }}</span>
+            <a href="" class="discrete link" @click.prevent="addSearchToken('account', scope.obj.actor.full_username)" :title="scope.obj.actor.full_username">{{ scope.obj.actor.preferred_username }}</a>
           </td>
           <td>
             <template v-if="!scope.obj.is_local">
               <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
                 <i class="wrench icon"></i>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</a>
             </template>
-            <span role="button" v-else class="ui tiny accent icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+            <a href="" v-else class="ui tiny accent icon link label" @click.prevent="addSearchToken('domain', scope.obj.domain)">
               <i class="home icon"></i>
               <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
-            </span>
+            </a>
           </td>
           <td>
-            <span
-              role="button"
+            <a
+              href=""
               class="discrete link"
-              @click="addSearchToken('privacy_level', scope.obj.privacy_level)"
+              @click.prevent="addSearchToken('privacy_level', scope.obj.privacy_level)"
               :title="sharedLabels.fields.privacy_level.shortChoices[scope.obj.privacy_level]">
               {{ sharedLabels.fields.privacy_level.shortChoices[scope.obj.privacy_level] }}
-            </span>
+            </a>
           </td>
           <td>
             {{ scope.obj.uploads_count }}
diff --git a/front/src/components/manage/library/TracksTable.vue b/front/src/components/manage/library/TracksTable.vue
index 80d8c6efeb9b9fc54a5e1364ae54c9100373a438..9c12ea11d92861f27b3a8ccd3aeeeab83780a10b 100644
--- a/front/src/components/manage/library/TracksTable.vue
+++ b/front/src/components/manage/library/TracksTable.vue
@@ -53,29 +53,29 @@
               <router-link :to="{name: 'manage.library.albums.detail', params: {id: scope.obj.album.id }}">
                 <i class="wrench icon"></i>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('album_id', scope.obj.album.id)" :title="scope.obj.album.title">{{ scope.obj.album.title }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('album_id', scope.obj.album.id)" :title="scope.obj.album.title">{{ scope.obj.album.title }}</a>
             </template>
           </td>
           <td>
             <router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.artist.id }}">
               <i class="wrench icon"></i>
             </router-link>
-            <span role="button" class="discrete link" @click="addSearchToken('artist_id', scope.obj.artist.id)" :title="scope.obj.artist.name">{{ scope.obj.artist.name }}</span>
+            <a href="" class="discrete link" @click.prevent="addSearchToken('artist_id', scope.obj.artist.id)" :title="scope.obj.artist.name">{{ scope.obj.artist.name }}</a>
           </td>
           <td>
             <template v-if="!scope.obj.is_local">
               <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
                 <i class="wrench icon"></i>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</a>
             </template>
-            <span role="button" v-else class="ui tiny accent icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+            <a href="" v-else class="ui tiny accent icon link label" @click.prevent="addSearchToken('domain', scope.obj.domain)">
               <i class="home icon"></i>
               <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
-            </span>
+            </a>
           </td>
           <td>
-            <span role="button" v-if="scope.obj.license" class="discrete link" @click="addSearchToken('license', scope.obj.license)" :title="scope.obj.license">{{ scope.obj.license }}</span>
+            <a href="" v-if="scope.obj.license" class="discrete link" @click.prevent="addSearchToken('license', scope.obj.license)" :title="scope.obj.license">{{ scope.obj.license }}</a>
             <translate v-else translate-context="*/*/*">N/A</translate>
           </td>
           <td>
diff --git a/front/src/components/manage/library/UploadsTable.vue b/front/src/components/manage/library/UploadsTable.vue
index 1063b3a4724a9a7364069843b5bd92cce7f8d16a..f3f50584ab3b73778858204edb6045b95a96d6e3 100644
--- a/front/src/components/manage/library/UploadsTable.vue
+++ b/front/src/components/manage/library/UploadsTable.vue
@@ -77,42 +77,42 @@
             <router-link :to="{name: 'manage.library.libraries.detail', params: {id: scope.obj.library.uuid }}">
               <i class="wrench icon"></i>
             </router-link>
-            <span role="button" class="discrete link"
-              @click="addSearchToken('library_id', scope.obj.library.id)"
+            <a href="" class="discrete link"
+              @click.prevent="addSearchToken('library_id', scope.obj.library.id)"
               :title="scope.obj.library.name">
               {{ scope.obj.library.name | truncate(20) }}
-            </span>
+            </a>
           </td>
           <td>
             <router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.library.actor.full_username }}">
             </router-link>
-            <span role="button" class="discrete link" @click="addSearchToken('account', scope.obj.library.actor.full_username)" :title="scope.obj.library.actor.full_username">{{ scope.obj.library.actor.preferred_username }}</span>
+            <a href="" class="discrete link" @click.prevent="addSearchToken('account', scope.obj.library.actor.full_username)" :title="scope.obj.library.actor.full_username">{{ scope.obj.library.actor.preferred_username }}</a>
           </td>
           <td>
             <template v-if="!scope.obj.is_local">
               <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
                 <i class="wrench icon"></i>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</a>
             </template>
-            <span role="button" v-else class="ui tiny accent icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+            <a href="" v-else class="ui tiny accent icon link label" @click.prevent="addSearchToken('domain', scope.obj.domain)">
               <i class="home icon"></i>
               <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
-            </span>
+            </a>
           </td>
           <td>
-            <span
-              role="button"
+            <a
+              href=""
               class="discrete link"
-              @click="addSearchToken('privacy_level', scope.obj.library.privacy_level)"
+              @click.prevent="addSearchToken('privacy_level', scope.obj.library.privacy_level)"
               :title="sharedLabels.fields.privacy_level.shortChoices[scope.obj.library.privacy_level]">
               {{ sharedLabels.fields.privacy_level.shortChoices[scope.obj.library.privacy_level] }}
-            </span>
+            </a>
           </td>
           <td>
-            <span class="discrete link" @click="addSearchToken('status', scope.obj.import_status)" :title="sharedLabels.fields.import_status.choices[scope.obj.import_status].help">
+            <a href="" class="discrete link" @click.prevent="addSearchToken('status', scope.obj.import_status)" :title="sharedLabels.fields.import_status.choices[scope.obj.import_status].help">
               {{ sharedLabels.fields.import_status.choices[scope.obj.import_status].label }}
-            </span>
+            </a>
             <button class="ui tiny basic icon button" :title="sharedLabels.fields.import_status.detailTitle" @click="detailedUpload = scope.obj; showUploadDetailModal = true">
               <i class="question circle outline icon"></i>
             </button>
diff --git a/front/src/components/manage/moderation/AccountsTable.vue b/front/src/components/manage/moderation/AccountsTable.vue
index 9b6782fc61bca38828dff21b2f8070b773f789f0..124efcbca07a519473612f7182abd6614457cebc 100644
--- a/front/src/components/manage/moderation/AccountsTable.vue
+++ b/front/src/components/manage/moderation/AccountsTable.vue
@@ -53,12 +53,12 @@
               <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
                 <i class="wrench icon"></i>
               </router-link>
-              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+              <a href="" class="discrete link" @click.prevent="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</a>
             </template>
-            <span role="button" v-else class="ui tiny accent icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+            <a href="" v-else class="ui tiny accent icon link label" @click.prevent="addSearchToken('domain', scope.obj.domain)">
               <i class="home icon"></i>
               <translate translate-context="Content/Moderation/*/Short, Noun">Local account</translate>
-            </span>
+            </a>
           </td>
           <td>
             {{ scope.obj.uploads_count }}
diff --git a/front/src/components/notifications/NotificationRow.vue b/front/src/components/notifications/NotificationRow.vue
index 3a014241cf85a59e4f39186f67c4211640d0cdfb..68a017d17650eea435caf91c2925ddd624f2eb16 100644
--- a/front/src/components/notifications/NotificationRow.vue
+++ b/front/src/components/notifications/NotificationRow.vue
@@ -21,12 +21,12 @@
     </td>
     <td><human-date :date="item.activity.creation_date" /></td>
     <td class="read collapsing">
-      <span @click="markRead(false)" role="button" v-if="item.is_read" :title="labels.markUnread">
+      <a href="" :aria-label="labels.markUnread" @click.prevent="markRead(false)" class="discrete link" v-if="item.is_read" :title="labels.markUnread">
         <i class="redo icon" />
-      </span>
-      <span @click="markRead(true)" role="button" v-else :title="labels.markRead">
+      </a>
+      <a href="" :aria-label="labels.markRead" @click.prevent="markRead(true)" class="discrete link" v-else :title="labels.markRead">
         <i class="check icon" />
-      </span>
+      </a>
     </td>
   </tr>
 </template>
diff --git a/front/src/components/playlists/PlaylistModal.vue b/front/src/components/playlists/PlaylistModal.vue
index 79e49a92ab405a7e0e8c3c22db45944da14e350d..ea63954b8ae543e8a920385351e2603552aa49b8 100644
--- a/front/src/components/playlists/PlaylistModal.vue
+++ b/front/src/components/playlists/PlaylistModal.vue
@@ -69,13 +69,13 @@
               <td><human-date :date="playlist.modification_date"></human-date></td>
               <td>{{ playlist.tracks_count }}</td>
               <td>
-                <div
+                <button
                   v-if="track"
                   class="ui success icon basic small right floated button"
                   :title="labels.addToPlaylist"
-                  @click="addToPlaylist(playlist.id, false)">
+                  @click.prevent="addToPlaylist(playlist.id, false)">
                   <i class="plus icon"></i> <translate translate-context="Popup/Playlist/Table.Button.Label/Verb">Add track</translate>
-                </div>
+                </button>
               </td>
             </tr>
           </tbody>
diff --git a/front/src/views/Notifications.vue b/front/src/views/Notifications.vue
index 84315af9f663ede4371222da47bdfed7300471be..7060762b383030895a4eadb9f438c7f4e2d8f1f5 100644
--- a/front/src/views/Notifications.vue
+++ b/front/src/views/Notifications.vue
@@ -72,13 +72,13 @@
           <input id="show-read-notifications" v-model="filters.is_read" type="checkbox">
           <label for="show-read-notifications"><translate translate-context="Content/Notifications/Form.Label/Verb">Show read notifications</translate></label>
         </div>
-        <div
+        <button
           v-if="filters.is_read === false && notifications.count > 0"
-          @click="markAllAsRead"
+          @click.prevent="markAllAsRead"
           class="ui basic labeled icon right floated button">
           <i class="ui check icon" />
           <translate translate-context="Content/Notifications/Button.Label/Verb">Mark all as read</translate>
-        </div>
+        </button>
         <div class="ui hidden divider" />
 
         <div v-if="isLoading" :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
diff --git a/front/src/views/channels/DetailBase.vue b/front/src/views/channels/DetailBase.vue
index a6385488da4b757485e67c89ce2e5af0ce4ec895..be8481dafbf6637ca33242e78944f265f1eecf10 100644
--- a/front/src/views/channels/DetailBase.vue
+++ b/front/src/views/channels/DetailBase.vue
@@ -76,32 +76,32 @@
                 <button class="ui right floated pointing dropdown icon small basic button" ref="dropdown" v-dropdown="{direction: 'downward'}">
                   <i class="ellipsis vertical icon"></i>
                   <div class="menu">
-                    <div
-                      role="button"
+                    <a
+                      href=""
                       v-if="totalTracks > 0"
-                      @click="showEmbedModal = !showEmbedModal"
+                      @click.prevent="showEmbedModal = !showEmbedModal"
                       class="basic item">
                       <i class="code icon"></i>
                       <translate translate-context="Content/*/Button.Label/Verb">Embed</translate>
-                    </div>
+                    </a>
                     <div class="divider"></div>
-                    <div
-                      role="button"
+                    <a
+                      href=""
                       class="basic item"
                       v-for="obj in getReportableObjs({account: object.attributed_to, channel: object})"
                       :key="obj.target.type + obj.target.id"
                       @click.stop.prevent="$store.dispatch('moderation/report', obj.target)">
                       <i class="share icon" /> {{ obj.label }}
-                    </div>
+                    </a>
 
                     <template v-if="isOwner">
                       <div class="divider"></div>
-                      <div
+                      <a
                         class="item"
-                        role="button"
-                        @click.stop="showEditModal = true">
+                        href=""
+                        @click.stop.prevent="showEditModal = true">
                         <translate translate-context="*/*/*/Verb">Edit…</translate>
-                      </div>
+                      </a>
                       <dangerous-button
                         :class="['ui', {loading: isLoading}, 'item']"
                         v-if="object"
diff --git a/front/src/views/content/libraries/FilesTable.vue b/front/src/views/content/libraries/FilesTable.vue
index deb0804a679c391eea92978a28dfd8d316814b3e..5481f368ac6a5b726f2590fe7ffbe048ae51906a 100644
--- a/front/src/views/content/libraries/FilesTable.vue
+++ b/front/src/views/content/libraries/FilesTable.vue
@@ -130,17 +130,19 @@
               </router-link>
             </td>
             <td>
-              <span
+              <a
+                href=""
                 class="discrete link"
-                @click="addSearchToken('artist', scope.obj.track.artist.name)"
-              >{{ scope.obj.track.artist.name|truncate(20) }}</span>
+                @click.prevent="addSearchToken('artist', scope.obj.track.artist.name)"
+              >{{ scope.obj.track.artist.name|truncate(20) }}</a>
             </td>
             <td>
-              <span
+              <a
+                href=""
                 v-if="scope.obj.track.album"
                 class="discrete link"
-                @click="addSearchToken('album', scope.obj.track.album.title)"
-              >{{ scope.obj.track.album.title|truncate(20) }}</span>
+                @click.prevent="addSearchToken('album', scope.obj.track.album.title)"
+              >{{ scope.obj.track.album.title|truncate(20) }}</a>
             </td>
           </template>
           <template v-else>
@@ -152,11 +154,12 @@
             <human-date :date="scope.obj.creation_date"></human-date>
           </td>
           <td>
-            <span
+            <a 
+              href=""
               class="discrete link"
-              @click="addSearchToken('status', scope.obj.import_status)"
+              @click.prevent="addSearchToken('status', scope.obj.import_status)"
               :title="sharedLabels.fields.import_status.choices[scope.obj.import_status].help"
-            >{{ sharedLabels.fields.import_status.choices[scope.obj.import_status].label }}</span>
+            >{{ sharedLabels.fields.import_status.choices[scope.obj.import_status].label }}</a>
             <button
               class="ui tiny basic icon button"
               :title="sharedLabels.fields.import_status.detailTitle"
diff --git a/front/src/views/content/remote/Card.vue b/front/src/views/content/remote/Card.vue
index 8be7463d45a160ff3a7b94dfb064367617409b17..3e082cee2b8fec8ab91c206cedc3edc4fb63d8d4 100644
--- a/front/src/views/content/remote/Card.vue
+++ b/front/src/views/content/remote/Card.vue
@@ -65,11 +65,11 @@
           <i class="warning download icon"></i>
           <translate translate-context="Content/Library/Card.List item">Scanned with errors</translate>
         </template>
-        <span class="link right floated" @click="showScan = !showScan">
+        <a href="" class="link right floated" @click.prevent="showScan = !showScan">
           <translate translate-context="Content/Library/Card.Button.Label/Noun">Details</translate>
           <i v-if="showScan" class="angle down icon" />
           <i v-else class="angle right icon" />
-        </span>
+        </a>
         <div v-if="showScan">
           <template v-if="latestScan.modification_date">
             <translate translate-context="Content/Library/Card.List item/Noun">Last update:</translate><human-date :date="latestScan.modification_date" /><br />
@@ -78,9 +78,9 @@
         </div>
       </div>
       <div v-if="displayScan && canLaunchScan" class="clearfix">
-        <span class="right floated link" @click="launchScan">
+        <a href="" class="right floated link" @click.prevent="launchScan">
           <translate translate-context="Content/Library/Card.Button.Label/Verb">Scan now</translate> <i class="paper plane icon" />
-        </span>
+        </a>
       </div>
     </div>
     <div class="extra content">
diff --git a/front/src/views/content/remote/Home.vue b/front/src/views/content/remote/Home.vue
index d9fc81ebcdf1dcf73e096f788f6bb464db188d6b..0a896c9def90e5ef635e6f03c8e56e0a8e2065f0 100644
--- a/front/src/views/content/remote/Home.vue
+++ b/front/src/views/content/remote/Home.vue
@@ -13,7 +13,9 @@
       </div>
       <template v-if="existingFollows && existingFollows.count > 0">
         <h2><translate translate-context="Content/Library/Title">Known libraries</translate></h2>
-        <i @click="fetch()" :class="['ui', 'circular', 'refresh', 'icon']" /> <translate translate-context="Content/*/Button.Label/Short, Verb">Refresh</translate>
+        <a href="" class="discrete link" @click.prevent="fetch()" >
+          <i :class="['ui', 'circular', 'refresh', 'icon']" /> <translate translate-context="Content/*/Button.Label/Short, Verb">Refresh</translate>
+        </a>
         <div class="ui hidden divider"></div>
         <div class="ui two cards">
           <library-card