diff --git a/apps/dashboard/js/dashboard.js b/apps/dashboard/js/dashboard.js
index 0fe2e3f29f53f24118b72ef5e7e039ed0a38b06f..f150e8365d9f90b1368aee91e117c3f91b768688 100644
Binary files a/apps/dashboard/js/dashboard.js and b/apps/dashboard/js/dashboard.js differ
diff --git a/apps/dashboard/js/dashboard.js.map b/apps/dashboard/js/dashboard.js.map
index 724389e384c43956ca7d95651b71e455738a7d42..9b05a25d76abf0034ab9f56a4277d6d8e4e5fdae 100644
Binary files a/apps/dashboard/js/dashboard.js.map and b/apps/dashboard/js/dashboard.js.map differ
diff --git a/apps/files/js/dist/files-app-settings.js b/apps/files/js/dist/files-app-settings.js
index 39f988e3fb5a980ebedd08da67310cd29e4343b0..7cfe6c565318eb1b2062bf9c2abf6f6d5e85d856 100644
Binary files a/apps/files/js/dist/files-app-settings.js and b/apps/files/js/dist/files-app-settings.js differ
diff --git a/apps/files/js/dist/files-app-settings.js.map b/apps/files/js/dist/files-app-settings.js.map
index dd8e279009ec2e1389194494201a11161bd4127e..482d1fcb8652757aaf1d41dc37d501d8c1710496 100644
Binary files a/apps/files/js/dist/files-app-settings.js.map and b/apps/files/js/dist/files-app-settings.js.map differ
diff --git a/apps/files/js/dist/personal-settings.js b/apps/files/js/dist/personal-settings.js
index b3ea05484d7e9f37f5515b733c81d5a78973857a..efc7e8176b58b85a75ad0f308e154ad8434c3aa3 100644
Binary files a/apps/files/js/dist/personal-settings.js and b/apps/files/js/dist/personal-settings.js differ
diff --git a/apps/files/js/dist/personal-settings.js.map b/apps/files/js/dist/personal-settings.js.map
index bd6ed98074b5e301869e2a205784ff94ba26de7b..ff4f1c613c819d05f41910ac1cca2f445f29d6f1 100644
Binary files a/apps/files/js/dist/personal-settings.js.map and b/apps/files/js/dist/personal-settings.js.map differ
diff --git a/apps/files/js/dist/sidebar.js b/apps/files/js/dist/sidebar.js
index f5dae581fa0754920d286418767b1ca2ed408984..4f3b85960b746deedc86c8b16f4ce05723a201ba 100644
Binary files a/apps/files/js/dist/sidebar.js and b/apps/files/js/dist/sidebar.js differ
diff --git a/apps/files/js/dist/sidebar.js.map b/apps/files/js/dist/sidebar.js.map
index 54d69846ad0b246f739c55b7fdb56cbf21af54c6..7e5ab3d895afbae9dfa325c05f1739e08afc62b0 100644
Binary files a/apps/files/js/dist/sidebar.js.map and b/apps/files/js/dist/sidebar.js.map differ
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 5e6225a48e9e7eb0f87c33be7ac4293be842be5f..ef5fffced402ee746889a854a26bedaa8ae62325 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -3700,7 +3700,22 @@
 			console.warn('registerTabView is deprecated! It will be removed in nextcloud 20.');
 			const enabled = tabView.canDisplay || undefined
 			if (tabView.id) {
-				OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab(tabView.id, tabView, enabled, true))
+				OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({
+					id: tabView.id, 
+					name: tabView.getLabel(),
+					icon: tabView.getIcon(),
+					mount: function(el, fileInfo) {
+						tabView.setFileInfo(fileInfo)
+						el.appendChild(tabView.el)
+					},
+					update: function(fileInfo) {
+						tabView.setFileInfo(fileInfo)
+					},
+					destroy: function() {
+						tabView.el.remove()
+					},
+					enabled: enabled
+				}))
 			}
 		},
 
diff --git a/apps/files/src/components/LegacyTab.vue b/apps/files/src/components/SidebarTab.vue
similarity index 51%
rename from apps/files/src/components/LegacyTab.vue
rename to apps/files/src/components/SidebarTab.vue
index c8308dd6209fc7b64e8948f3dbc17ac4cd0bf98b..1fc93486bc0044b6a5248adf716a93c0df996c40 100644
--- a/apps/files/src/components/LegacyTab.vue
+++ b/apps/files/src/components/SidebarTab.vue
@@ -1,3 +1,4 @@
+
 <!--
   - @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
   -
@@ -19,74 +20,106 @@
   - along with this program. If not, see <http://www.gnu.org/licenses/>.
   -
   -->
-
 <template>
 	<AppSidebarTab
 		:id="id"
-		:icon="icon"
+		ref="tab"
 		:name="name"
-		:active-tab="activeTab" />
+		:icon="icon">
+		<!-- Fallback loading -->
+		<EmptyContent v-if="loading" icon="icon-loading" />
+
+		<!-- Using a dummy div as Vue mount replace the element directly
+			It does NOT append to the content -->
+		<div ref="mount" />
+	</AppSidebarTab>
 </template>
+
 <script>
 import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab'
+import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
 
 export default {
-	name: 'LegacyTab',
+	name: 'SidebarTab',
+
 	components: {
 		AppSidebarTab,
+		EmptyContent,
 	},
+
 	props: {
-		component: {
+		fileInfo: {
 			type: Object,
+			default: () => {},
 			required: true,
 		},
 		id: {
 			type: String,
 			required: true,
 		},
-		fileInfo: {
-			type: Object,
-			default: () => {},
+		name: {
+			type: String,
 			required: true,
 		},
-	},
-	computed: {
-		icon() {
-			return this.component.getIcon()
+		icon: {
+			type: String,
+			required: true,
 		},
-		name() {
-			return this.component.getLabel()
+
+		/**
+		 * Lifecycle methods.
+		 * They are prefixed with `on` to avoid conflict with Vue
+		 * methods like this.destroy
+		 */
+		onMount: {
+			type: Function,
+			required: true,
+		},
+		onUpdate: {
+			type: Function,
+			required: true,
 		},
-		order() {
-			return this.component.order
-				? this.component.order
-				: 0
+		onDestroy: {
+			type: Function,
+			required: true,
 		},
-		// needed because AppSidebarTab also uses $parent.activeTab
+	},
+
+	data() {
+		return {
+			loading: true,
+		}
+	},
+
+	computed: {
+		// TODO: implement a better way to force pass a prop from Sidebar
 		activeTab() {
 			return this.$parent.activeTab
 		},
 	},
+
 	watch: {
-		fileInfo(fileInfo) {
-			if (fileInfo) {
-				this.setFileInfo(fileInfo)
+		async fileInfo(newFile, oldFile) {
+			// Update fileInfo on change
+			if (newFile.id !== oldFile.id) {
+				this.loading = true
+				await this.onUpdate(this.fileInfo)
+				this.loading = false
 			}
 		},
 	},
-	mounted() {
-		// append the backbone element and set the FileInfo
-		this.component.$el.appendTo(this.$el)
-	},
-	beforeDestroy() {
-		this.component.remove()
+
+	async mounted() {
+		this.loading = true
+		// Mount the tab:  mounting point,   fileInfo,      vue context
+		await this.onMount(this.$refs.mount, this.fileInfo, this.$refs.tab)
+		this.loading = false
 	},
-	methods: {
-		setFileInfo(fileInfo) {
-			this.component.setFileInfo(new OCA.Files.FileInfoModel(fileInfo))
-		},
+
+	async beforeDestroy() {
+		// unmount the tab
+		await this.onDestroy()
 	},
+
 }
 </script>
-<style>
-</style>
diff --git a/apps/files/src/models/Tab.js b/apps/files/src/models/Tab.js
index fd1ea9888d97cd19a3e7191ef0371fca2d8dd866..2c587e5f70a743714b1e4dc5cb5cccde8bca2cd2 100644
--- a/apps/files/src/models/Tab.js
+++ b/apps/files/src/models/Tab.js
@@ -22,32 +22,61 @@
 
 export default class Tab {
 
-	#component
-	#legacy
 	#id
+	#name
+	#icon
+	#mount
+	#update
+	#destroy
 	#enabled
 
 	/**
 	 * Create a new tab instance
 	 *
-	 * @param {string} id the unique id of this tab
-	 * @param {Object} component the vue component
-	 * @param {Function} [enabled] function that returns if the tab should be shown or not
-	 * @param {boolean} [legacy] is this a legacy tab
+	 * @param {Object} options destructuring object
+	 * @param {string} options.id the unique id of this tab
+	 * @param {string} options.name the translated tab name
+	 * @param {string} options.icon the vue component
+	 * @param {Function} options.mount function to mount the tab
+	 * @param {Function} options.update function to update the tab
+	 * @param {Function} options.destroy function to destroy the tab
+	 * @param {Function} [options.enabled] define conditions whether this tab is active. Must returns a boolean
 	 */
-	constructor(id, component, enabled = () => true, legacy) {
+	constructor({ id, name, icon, mount, update, destroy, enabled } = {}) {
+		if (enabled === undefined) {
+			enabled = () => true
+		}
+
+		// Sanity checks
+		if (typeof id !== 'string' || id.trim() === '') {
+			throw new Error('The id argument is not a valid string')
+		}
+		if (typeof name !== 'string' || name.trim() === '') {
+			throw new Error('The name argument is not a valid string')
+		}
+		if (typeof icon !== 'string' || icon.trim() === '') {
+			throw new Error('The icon argument is not a valid string')
+		}
+		if (typeof mount !== 'function') {
+			throw new Error('The mount argument should be a function')
+		}
+		if (typeof update !== 'function') {
+			throw new Error('The update argument should be a function')
+		}
+		if (typeof destroy !== 'function') {
+			throw new Error('The destroy argument should be a function')
+		}
 		if (typeof enabled !== 'function') {
 			throw new Error('The enabled argument should be a function')
 		}
 
 		this.#id = id
-		this.#component = component
+		this.#name = name
+		this.#icon = icon
+		this.#mount = mount
+		this.#update = update
+		this.#destroy = destroy
 		this.#enabled = enabled
-		this.#legacy = legacy === true
-
-		if (this.#legacy) {
-			console.warn('Legacy tabs are deprecated! They will be removed in nextcloud 20.')
-		}
 
 	}
 
@@ -55,16 +84,28 @@ export default class Tab {
 		return this.#id
 	}
 
-	get component() {
-		return this.#component
+	get name() {
+		return this.#name
 	}
 
-	get isEnabled() {
-		return this.#enabled
+	get icon() {
+		return this.#icon
 	}
 
-	get isLegacyTab() {
-		return this.#legacy === true
+	get mount() {
+		return this.#mount
+	}
+
+	get update() {
+		return this.#update
+	}
+
+	get destroy() {
+		return this.#destroy
+	}
+
+	get enabled() {
+		return this.#enabled
 	}
 
 }
diff --git a/apps/files/src/sidebar.js b/apps/files/src/sidebar.js
index f815a498938eced616b5acf1afefe6b0306ba4b6..54293bd24c83d963bdb7f6112a88b5a41f20c3dd 100644
--- a/apps/files/src/sidebar.js
+++ b/apps/files/src/sidebar.js
@@ -21,12 +21,11 @@
  */
 
 import Vue from 'vue'
+import { translate as t } from '@nextcloud/l10n'
+
 import SidebarView from './views/Sidebar.vue'
 import Sidebar from './services/Sidebar'
 import Tab from './models/Tab'
-import VueClipboard from 'vue-clipboard2'
-
-Vue.use(VueClipboard)
 
 Vue.prototype.t = t
 
diff --git a/apps/files/src/views/Sidebar.vue b/apps/files/src/views/Sidebar.vue
index 1fc89c6a7ee6374f3763c7316adce7ebbed9fee3..664bc6f407517a17cc3fcf90181a3c5fc583f36e 100644
--- a/apps/files/src/views/Sidebar.vue
+++ b/apps/files/src/views/Sidebar.vue
@@ -52,34 +52,38 @@
 		</template>
 
 		<!-- Error display -->
-		<div v-if="error" class="emptycontent">
-			<div class="icon-error" />
-			<h2>{{ error }}</h2>
-		</div>
+		<EmptyContent v-if="error" icon="icon-error">
+			{{ error }}
+		</EmptyContent>
 
-		<!-- If fileInfo fetch is complete, display tabs -->
+		<!-- If fileInfo fetch is complete, render tabs -->
 		<template v-for="tab in tabs" v-else-if="fileInfo">
-			<component
-				:is="tabComponent(tab).is"
-				v-if="canDisplay(tab)"
+			<!-- Hide them if we're loading another file but keep them mounted -->
+			<SidebarTab
+				v-if="tab.enabled(fileInfo)"
+				v-show="!loading"
 				:id="tab.id"
 				:key="tab.id"
-				:component="tabComponent(tab).component"
 				:name="tab.name"
-				:dav-path="davPath"
+				:icon="tab.icon"
+				:on-mount="tab.mount"
+				:on-update="tab.update"
+				:on-destroy="tab.destroy"
 				:file-info="fileInfo" />
 		</template>
 	</AppSidebar>
 </template>
 <script>
+import { encodePath } from '@nextcloud/paths'
 import $ from 'jquery'
 import axios from '@nextcloud/axios'
 import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar'
 import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
+import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
+
 import FileInfo from '../services/FileInfo'
-import LegacyTab from '../components/LegacyTab'
+import SidebarTab from '../components/SidebarTab'
 import LegacyView from '../components/LegacyView'
-import { encodePath } from '@nextcloud/paths'
 
 export default {
 	name: 'Sidebar',
@@ -87,7 +91,9 @@ export default {
 	components: {
 		ActionButton,
 		AppSidebar,
+		EmptyContent,
 		LegacyView,
+		SidebarTab,
 	},
 
 	data() {
@@ -95,6 +101,7 @@ export default {
 			// reactive state
 			Sidebar: OCA.Files.Sidebar.state,
 			error: null,
+			loading: true,
 			fileInfo: null,
 			starLoading: false,
 		}
@@ -185,15 +192,16 @@ export default {
 		appSidebar() {
 			if (this.fileInfo) {
 				return {
-					background: this.background,
+					'data-mimetype': this.fileInfo.mimetype,
+					'star-loading': this.starLoading,
 					active: this.activeTab,
+					background: this.background,
 					class: { 'has-preview': this.fileInfo.hasPreview },
 					compact: !this.fileInfo.hasPreview,
-					'star-loading': this.starLoading,
+					loading: this.loading,
 					starred: this.fileInfo.isFavourited,
 					subtitle: this.subtitle,
 					title: this.fileInfo.name,
-					'data-mimetype': this.fileInfo.mimetype,
 				}
 			} else if (this.error) {
 				return {
@@ -201,12 +209,12 @@ export default {
 					subtitle: '',
 					title: '',
 				}
-			} else {
-				return {
-					class: 'icon-loading',
-					subtitle: '',
-					title: '',
-				}
+			}
+			// no fileInfo yet, showing empty data
+			return {
+				loading: this.loading,
+				subtitle: '',
+				title: '',
 			}
 		},
 
@@ -241,35 +249,6 @@ export default {
 		},
 	},
 
-	watch: {
-		// update the sidebar data
-		async file(curr, prev) {
-			this.resetData()
-			if (curr && curr.trim() !== '') {
-				try {
-					this.fileInfo = await FileInfo(this.davPath)
-					// adding this as fallback because other apps expect it
-					this.fileInfo.dir = this.file.split('/').slice(0, -1).join('/')
-
-					// DEPRECATED legacy views
-					// TODO: remove
-					this.views.forEach(view => {
-						view.setFileInfo(this.fileInfo)
-					})
-
-					this.$nextTick(() => {
-						if (this.$refs.sidebar) {
-							this.$refs.sidebar.updateTabs()
-						}
-					})
-				} catch (error) {
-					this.error = t('files', 'Error while loading the file data')
-					console.error('Error while loading the file data', error)
-				}
-			}
-		},
-	},
-
 	methods: {
 		/**
 		 * Can this tab be displayed ?
@@ -278,14 +257,14 @@ export default {
 		 * @returns {boolean}
 		 */
 		canDisplay(tab) {
-			return tab.isEnabled(this.fileInfo)
+			return tab.enabled(this.fileInfo)
 		},
 		resetData() {
 			this.error = null
 			this.fileInfo = null
 			this.$nextTick(() => {
-				if (this.$refs.sidebar) {
-					this.$refs.sidebar.updateTabs()
+				if (this.$refs.tabs) {
+					this.$refs.tabs.updateTabs()
 				}
 			})
 		},
@@ -327,18 +306,6 @@ export default {
 			return OC.MimeType.getIconUrl(mimeType)
 		},
 
-		tabComponent(tab) {
-			if (tab.isLegacyTab) {
-				return {
-					is: LegacyTab,
-					component: tab.component,
-				}
-			}
-			return {
-				is: tab.component,
-			}
-		},
-
 		/**
 		 * Set current active tab
 		 *
@@ -415,9 +382,11 @@ export default {
 			// update current opened file
 			this.Sidebar.file = path
 
-			// reset previous data
-			this.resetData()
 			if (path && path.trim() !== '') {
+				// reset data, keep old fileInfo to not reload all tabs and just hide them
+				this.error = null
+				this.loading = true
+
 				try {
 					this.fileInfo = await FileInfo(this.davPath)
 					// adding this as fallback because other apps expect it
@@ -430,8 +399,8 @@ export default {
 					})
 
 					this.$nextTick(() => {
-						if (this.$refs.sidebar) {
-							this.$refs.sidebar.updateTabs()
+						if (this.$refs.tabs) {
+							this.$refs.tabs.updateTabs()
 						}
 					})
 				} catch (error) {
@@ -439,6 +408,8 @@ export default {
 					console.error('Error while loading the file data', error)
 
 					throw new Error(error)
+				} finally {
+					this.loading = false
 				}
 			}
 		},
diff --git a/apps/files_sharing/js/dist/additionalScripts.js b/apps/files_sharing/js/dist/additionalScripts.js
index b889d5d7b78c102490a60124c995ab8df0796388..58583f5d47cd0ad6c984161c5ce680041aed4f7c 100644
Binary files a/apps/files_sharing/js/dist/additionalScripts.js and b/apps/files_sharing/js/dist/additionalScripts.js differ
diff --git a/apps/files_sharing/js/dist/additionalScripts.js.map b/apps/files_sharing/js/dist/additionalScripts.js.map
index 07cff7cb16cf950578fffdd30edf579d7246c9bf..ab39bf2cfafef4b32269a1cb041274829e48c1dc 100644
Binary files a/apps/files_sharing/js/dist/additionalScripts.js.map and b/apps/files_sharing/js/dist/additionalScripts.js.map differ
diff --git a/apps/files_sharing/js/dist/collaboration.js b/apps/files_sharing/js/dist/collaboration.js
index e082be7ccf36d572ba6299fb7e57eb18d50987b6..a3d96c885545fbf15f8c1d60fe499f26ba71b15f 100644
Binary files a/apps/files_sharing/js/dist/collaboration.js and b/apps/files_sharing/js/dist/collaboration.js differ
diff --git a/apps/files_sharing/js/dist/collaboration.js.map b/apps/files_sharing/js/dist/collaboration.js.map
index 7f3b0c6913199f3a84920a2bb847bfa237c340e1..14da3bdeb6ff0f183acda1693f3100a7453552a1 100644
Binary files a/apps/files_sharing/js/dist/collaboration.js.map and b/apps/files_sharing/js/dist/collaboration.js.map differ
diff --git a/apps/files_sharing/js/dist/files_sharing.js b/apps/files_sharing/js/dist/files_sharing.js
index 0cf5890c43bd7e9cfe7dfcb21956a9356762e15f..333c5125a2e1819e8a7b44fb17f3d398b7e9eece 100644
Binary files a/apps/files_sharing/js/dist/files_sharing.js and b/apps/files_sharing/js/dist/files_sharing.js differ
diff --git a/apps/files_sharing/js/dist/files_sharing.js.map b/apps/files_sharing/js/dist/files_sharing.js.map
index 88e5f079b31c9c73a76ee0088ccfac0f0bbe1ff6..a2e3051c99575991b41d6fe3004c5d7a6c82fa8e 100644
Binary files a/apps/files_sharing/js/dist/files_sharing.js.map and b/apps/files_sharing/js/dist/files_sharing.js.map differ
diff --git a/apps/files_sharing/js/dist/files_sharing_tab.js b/apps/files_sharing/js/dist/files_sharing_tab.js
index 489321488dc2cc95c1f57409a95ba3e0751ff085..882585efdb54d422840131b535d497143c62a627 100644
Binary files a/apps/files_sharing/js/dist/files_sharing_tab.js and b/apps/files_sharing/js/dist/files_sharing_tab.js differ
diff --git a/apps/files_sharing/js/dist/files_sharing_tab.js.map b/apps/files_sharing/js/dist/files_sharing_tab.js.map
index a2d6a3463727a4726438396dc5d7417de18c65c4..3cf70cc039075deb9bd4e179a8e36c8fad3473c5 100644
Binary files a/apps/files_sharing/js/dist/files_sharing_tab.js.map and b/apps/files_sharing/js/dist/files_sharing_tab.js.map differ
diff --git a/apps/files_sharing/js/dist/main.js b/apps/files_sharing/js/dist/main.js
index 43ce0473ccebbb56fa4d3120aed8955baaf0464a..d42e9ee83f7486be02aed762ccfa1c6765024c15 100644
Binary files a/apps/files_sharing/js/dist/main.js and b/apps/files_sharing/js/dist/main.js differ
diff --git a/apps/files_sharing/js/dist/main.js.map b/apps/files_sharing/js/dist/main.js.map
index 826d9da580efad306f081566c25f92053a43f5ce..e72e60559a491ef7c1729ffe065a0303487acfa7 100644
Binary files a/apps/files_sharing/js/dist/main.js.map and b/apps/files_sharing/js/dist/main.js.map differ
diff --git a/apps/files_sharing/js/dist/personal-settings.js b/apps/files_sharing/js/dist/personal-settings.js
index 534d7474ff105b7a4b69ad61f79e5c7e1d3053af..faf432178bb938c674394b5a5a5b0ea74bd96c5d 100644
Binary files a/apps/files_sharing/js/dist/personal-settings.js and b/apps/files_sharing/js/dist/personal-settings.js differ
diff --git a/apps/files_sharing/js/dist/personal-settings.js.map b/apps/files_sharing/js/dist/personal-settings.js.map
index 935dae371f11937e7a6513a07195e4718550f896..ab87262a6d010a2b97c4f956f24cde46dff623c7 100644
Binary files a/apps/files_sharing/js/dist/personal-settings.js.map and b/apps/files_sharing/js/dist/personal-settings.js.map differ
diff --git a/apps/files_sharing/src/files_sharing_tab.js b/apps/files_sharing/src/files_sharing_tab.js
index ffb6cdec30a6e123abaf2b1ca4a3c9b65d35d1e7..c6ed380a6c57f7940c3f215c4f569384f42abd10 100644
--- a/apps/files_sharing/src/files_sharing_tab.js
+++ b/apps/files_sharing/src/files_sharing_tab.js
@@ -19,11 +19,13 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+import Vue from 'vue'
+import VueClipboard from 'vue-clipboard2'
+import { translate as t, translatePlural as n } from '@nextcloud/l10n'
 
 import SharingTab from './views/SharingTab'
 import ShareSearch from './services/ShareSearch'
 import ExternalLinkActions from './services/ExternalLinkActions'
-
 import TabSections from './services/TabSections'
 
 // Init Sharing Tab Service
@@ -34,8 +36,40 @@ Object.assign(window.OCA.Sharing, { ShareSearch: new ShareSearch() })
 Object.assign(window.OCA.Sharing, { ExternalLinkActions: new ExternalLinkActions() })
 Object.assign(window.OCA.Sharing, { ShareTabSections: new TabSections() })
 
+Vue.prototype.t = t
+Vue.prototype.n = n
+Vue.use(VueClipboard)
+
+// Init Sharing tab component
+const View = Vue.extend(SharingTab)
+let TabInstance = null
+
 window.addEventListener('DOMContentLoaded', function() {
 	if (OCA.Files && OCA.Files.Sidebar) {
-		OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab('sharing', SharingTab))
+		OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({
+			id: 'sharing',
+			name: t('files_sharing', 'Sharing'),
+			icon: 'icon-share',
+
+			async mount(el, fileInfo, context) {
+				if (TabInstance) {
+					TabInstance.$destroy()
+				}
+				TabInstance = new View({
+					// Better integration with vue parent component
+					parent: context,
+				})
+				// Only mount after we have all the info we need
+				await TabInstance.update(fileInfo)
+				TabInstance.$mount(el)
+			},
+			update(fileInfo) {
+				TabInstance.update(fileInfo)
+			},
+			destroy() {
+				TabInstance.$destroy()
+				TabInstance = null
+			},
+		}))
 	}
 })
diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue
index 40c8572912fcb4e0970cbebfaa9c17aacf107384..0371be76a704188d8ea363919dfb1d9490a13810 100644
--- a/apps/files_sharing/src/views/SharingTab.vue
+++ b/apps/files_sharing/src/views/SharingTab.vue
@@ -21,10 +21,7 @@
   -->
 
 <template>
-	<Tab :id="id"
-		:icon="icon"
-		:name="name"
-		:class="{ 'icon-loading': loading }">
+	<div :class="{ 'icon-loading': loading }">
 		<!-- error message -->
 		<div v-if="error" class="emptycontent">
 			<div class="icon icon-error" />
@@ -84,7 +81,7 @@
 				<component :is="section($refs['section-'+index], fileInfo)" :file-info="fileInfo" />
 			</div>
 		</template>
-	</Tab>
+	</div>
 </template>
 
 <script>
@@ -92,7 +89,6 @@ import { CollectionList } from 'nextcloud-vue-collections'
 import { generateOcsUrl } from '@nextcloud/router'
 import Avatar from '@nextcloud/vue/dist/Components/Avatar'
 import axios from '@nextcloud/axios'
-import Tab from '@nextcloud/vue/dist/Components/AppSidebarTab'
 
 import { shareWithTitle } from '../utils/SharedWithMe'
 import Share from '../models/Share'
@@ -117,56 +113,29 @@ export default {
 		SharingInput,
 		SharingLinkList,
 		SharingList,
-		Tab,
 	},
 
 	mixins: [ShareTypes],
 
-	props: {
-		fileInfo: {
-			type: Object,
-			default: () => {},
-			required: true,
-		},
-	},
-
 	data() {
 		return {
 			error: '',
 			expirationInterval: null,
-			icon: 'icon-share',
 			loading: true,
-			name: t('files_sharing', 'Sharing'),
+
+			fileInfo: null,
+
 			// reshare Share object
 			reshare: null,
 			sharedWithMe: {},
 			shares: [],
 			linkShares: [],
+
 			sections: OCA.Sharing.ShareTabSections.getSections(),
 		}
 	},
 
 	computed: {
-		/**
-		 * Needed to differenciate the tabs
-		 * pulled from the AppSidebarTab component
-		 *
-		 * @returns {string}
-		 */
-		id() {
-			return 'sharing'
-		},
-
-		/**
-		 * Returns the current active tab
-		 * needed because AppSidebarTab also uses $parent.activeTab
-		 *
-		 * @returns {string}
-		 */
-		activeTab() {
-			return this.$parent.activeTab
-		},
-
 		/**
 		 * Is this share shared with me?
 		 *
@@ -182,20 +151,17 @@ export default {
 		},
 	},
 
-	watch: {
-		fileInfo(newFile, oldFile) {
-			if (newFile.id !== oldFile.id) {
-				this.resetState()
-				this.getShares()
-			}
+	methods: {
+		/**
+		 * Update current fileInfo and fetch new data
+		 * @param {Object} fileInfo the current file FileInfo
+		 */
+		async update(fileInfo) {
+			this.fileInfo = fileInfo
+			this.resetState()
+			this.getShares()
 		},
-	},
-
-	beforeMount() {
-		this.getShares()
-	},
 
-	methods: {
 		/**
 		 * Get the existing shares infos
 		 */
@@ -248,6 +214,7 @@ export default {
 			this.error = ''
 			this.sharedWithMe = {}
 			this.shares = []
+			this.linkShares = []
 		},
 
 		/**
@@ -341,7 +308,3 @@ export default {
 	},
 }
 </script>
-
-<style lang="scss" scoped>
-
-</style>
diff --git a/apps/settings/js/vue-settings-admin-security.js b/apps/settings/js/vue-settings-admin-security.js
index 00d3d82db6b9b458da36cd4b91e9437d753b9f1e..b0e01957d140daf33b9850e6fd79accb02213692 100644
Binary files a/apps/settings/js/vue-settings-admin-security.js and b/apps/settings/js/vue-settings-admin-security.js differ
diff --git a/apps/settings/js/vue-settings-admin-security.js.map b/apps/settings/js/vue-settings-admin-security.js.map
index 121f282595cea70928a8952b69e6f955ba699abe..1909e99e0c105197080de204bb522f1de8c09300 100644
Binary files a/apps/settings/js/vue-settings-admin-security.js.map and b/apps/settings/js/vue-settings-admin-security.js.map differ
diff --git a/apps/settings/js/vue-settings-apps-users-management.js b/apps/settings/js/vue-settings-apps-users-management.js
index 28dd6bf424198a3095647b2b49f79649960e62b1..f0ab36bc568fe64ad60561b26f31ca32ba9a7ea4 100644
Binary files a/apps/settings/js/vue-settings-apps-users-management.js and b/apps/settings/js/vue-settings-apps-users-management.js differ
diff --git a/apps/settings/js/vue-settings-apps-users-management.js.map b/apps/settings/js/vue-settings-apps-users-management.js.map
index f7673924decfc092e629841f33f5d84ae1357d45..78dddb16fe8590bd93106152218be65021a9ba78 100644
Binary files a/apps/settings/js/vue-settings-apps-users-management.js.map and b/apps/settings/js/vue-settings-apps-users-management.js.map differ
diff --git a/apps/settings/js/vue-settings-personal-security.js b/apps/settings/js/vue-settings-personal-security.js
index 6faadef7a32ba66b46f4306e2af6c634d22e9f2c..16346e91a4cee6a085911ecc110e63ef4c2a2b78 100644
Binary files a/apps/settings/js/vue-settings-personal-security.js and b/apps/settings/js/vue-settings-personal-security.js differ
diff --git a/apps/settings/js/vue-settings-personal-security.js.map b/apps/settings/js/vue-settings-personal-security.js.map
index c805a4fb67432ba120fe0db686b8a6552b5d13e7..0623ec4b577456522a7f2400cb07f298dcf2328c 100644
Binary files a/apps/settings/js/vue-settings-personal-security.js.map and b/apps/settings/js/vue-settings-personal-security.js.map differ
diff --git a/apps/settings/js/vue-settings-personal-webauthn.js b/apps/settings/js/vue-settings-personal-webauthn.js
index 446c7433bf5476d50eb86eb3c8d3c1481914345c..6846f6505b9bae6311d1ffcb9475516e0a598d2b 100644
Binary files a/apps/settings/js/vue-settings-personal-webauthn.js and b/apps/settings/js/vue-settings-personal-webauthn.js differ
diff --git a/apps/settings/js/vue-settings-personal-webauthn.js.map b/apps/settings/js/vue-settings-personal-webauthn.js.map
index 354ed83c220495ae4a9d0ac1c8b47addb8878767..d74c11449f128fa592ade9e058a53a950c7a0dde 100644
Binary files a/apps/settings/js/vue-settings-personal-webauthn.js.map and b/apps/settings/js/vue-settings-personal-webauthn.js.map differ
diff --git a/apps/settings/js/vue-vendors-settings-apps-bde5ca85af7ad0d933a8.js b/apps/settings/js/vue-vendors-settings-apps-bde5ca85af7ad0d933a8.js
new file mode 100644
index 0000000000000000000000000000000000000000..699409e865bd7ec4c69910db6e4b60646abbd4d0
Binary files /dev/null and b/apps/settings/js/vue-vendors-settings-apps-bde5ca85af7ad0d933a8.js differ
diff --git a/apps/settings/js/vue-vendors-settings-apps-bde5ca85af7ad0d933a8.js.map b/apps/settings/js/vue-vendors-settings-apps-bde5ca85af7ad0d933a8.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..21e77b72670903acc8ca964b5cdbf4c117828c8d
Binary files /dev/null and b/apps/settings/js/vue-vendors-settings-apps-bde5ca85af7ad0d933a8.js.map differ
diff --git a/apps/settings/js/vue-vendors-settings-apps-settings-users-f077c891fa908a10fb34.js b/apps/settings/js/vue-vendors-settings-apps-settings-users-f077c891fa908a10fb34.js
new file mode 100644
index 0000000000000000000000000000000000000000..26ac86c0e32edd51b196fd02ff73afec36fc882a
Binary files /dev/null and b/apps/settings/js/vue-vendors-settings-apps-settings-users-f077c891fa908a10fb34.js differ
diff --git a/apps/settings/js/vue-vendors-settings-apps-settings-users-f077c891fa908a10fb34.js.map b/apps/settings/js/vue-vendors-settings-apps-settings-users-f077c891fa908a10fb34.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..ab87e29fe8cbd4ad2c6720129f917f77ce0dbba3
Binary files /dev/null and b/apps/settings/js/vue-vendors-settings-apps-settings-users-f077c891fa908a10fb34.js.map differ
diff --git a/apps/settings/js/vue-vendors-settings-users-3a6581e78bc592eedd33.js b/apps/settings/js/vue-vendors-settings-users-3a6581e78bc592eedd33.js
new file mode 100644
index 0000000000000000000000000000000000000000..e81090d3dd262841b0cd1defe2ed2420e4fde988
Binary files /dev/null and b/apps/settings/js/vue-vendors-settings-users-3a6581e78bc592eedd33.js differ
diff --git a/apps/settings/js/vue-vendors-settings-users-3a6581e78bc592eedd33.js.map b/apps/settings/js/vue-vendors-settings-users-3a6581e78bc592eedd33.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..035d8cef347144cad18cf7db66094003d892fac5
Binary files /dev/null and b/apps/settings/js/vue-vendors-settings-users-3a6581e78bc592eedd33.js.map differ
diff --git a/apps/updatenotification/js/updatenotification.js b/apps/updatenotification/js/updatenotification.js
index 13d1a304b2ec97fb99ad4774d5767f04fefd8aa3..7c0daf5f7d4ccf7eb44a91337a27a8b3a8b9b035 100644
Binary files a/apps/updatenotification/js/updatenotification.js and b/apps/updatenotification/js/updatenotification.js differ
diff --git a/apps/updatenotification/js/updatenotification.js.map b/apps/updatenotification/js/updatenotification.js.map
index e744acd9efe952ff97f135df03f2d2939e099c63..e671bd0a233fcdce37e4e69c3d5a9bbd6da19c95 100644
Binary files a/apps/updatenotification/js/updatenotification.js.map and b/apps/updatenotification/js/updatenotification.js.map differ
diff --git a/apps/user_status/js/dashboard.js b/apps/user_status/js/dashboard.js
index 774e1653399e1e6a819bc51e7737388d34cd6737..e71b10e2262ac5bb460c3b5dfbe9a29db744c986 100644
Binary files a/apps/user_status/js/dashboard.js and b/apps/user_status/js/dashboard.js differ
diff --git a/apps/user_status/js/dashboard.js.map b/apps/user_status/js/dashboard.js.map
index 8d89fe07ae7deeec80bd35ca6f0ae33d4b46c704..8c7522f54e48a8a216e53ceb4702d78db1b749bf 100644
Binary files a/apps/user_status/js/dashboard.js.map and b/apps/user_status/js/dashboard.js.map differ
diff --git a/apps/user_status/js/user-status-menu.js b/apps/user_status/js/user-status-menu.js
index 257499c48be65acd8c8ac3414861408385361c8f..9b9d9b517dffb816c9e61355ce14e6ed81293fa9 100644
Binary files a/apps/user_status/js/user-status-menu.js and b/apps/user_status/js/user-status-menu.js differ
diff --git a/apps/user_status/js/user-status-menu.js.map b/apps/user_status/js/user-status-menu.js.map
index 9fdef2fca35f4ac0715f0434a2c6fcb4f0735e7d..33c7842835e49a1bb16a8ccd3fb1141ef43c9111 100644
Binary files a/apps/user_status/js/user-status-menu.js.map and b/apps/user_status/js/user-status-menu.js.map differ
diff --git a/apps/user_status/js/vendors-user-status-modal.js b/apps/user_status/js/vendors-user-status-modal.js
index 69fc2571bd6eb6992585bb6442a7d32988acdac4..6260a4ac518c4b69f855b599bb96329f92c4bd07 100644
Binary files a/apps/user_status/js/vendors-user-status-modal.js and b/apps/user_status/js/vendors-user-status-modal.js differ
diff --git a/apps/user_status/js/vendors-user-status-modal.js.map b/apps/user_status/js/vendors-user-status-modal.js.map
index 0bee4948ad1569c1978fc32743fa877549e8b18b..cdab8ed16cd8cb2205c3f75f0cc6401f20a87bac 100644
Binary files a/apps/user_status/js/vendors-user-status-modal.js.map and b/apps/user_status/js/vendors-user-status-modal.js.map differ
diff --git a/apps/weather_status/js/weather-status.js b/apps/weather_status/js/weather-status.js
index 8f02cf2028c68c71c6afff9ec5142cbd8d4a49e5..79699909614a3207e0f5bd062d9e0e927fe5db60 100644
Binary files a/apps/weather_status/js/weather-status.js and b/apps/weather_status/js/weather-status.js differ
diff --git a/apps/weather_status/js/weather-status.js.map b/apps/weather_status/js/weather-status.js.map
index 4c5eb21c70a612246bdbdd86f3ba3ee1a1ee4a44..104bb806b6d5020a24fe512e3cf217808bcded06 100644
Binary files a/apps/weather_status/js/weather-status.js.map and b/apps/weather_status/js/weather-status.js.map differ
diff --git a/apps/workflowengine/js/workflowengine.js b/apps/workflowengine/js/workflowengine.js
index d83ae8c7e9764566739a6d56eb309251d2cd3858..b9c7f21f40d91961310ef195387a0cca6396e807 100644
Binary files a/apps/workflowengine/js/workflowengine.js and b/apps/workflowengine/js/workflowengine.js differ
diff --git a/apps/workflowengine/js/workflowengine.js.map b/apps/workflowengine/js/workflowengine.js.map
index c4ebd0ea65cae57509f547cac77c06e15dc06ada..f8b32a78fc78c8e16ad1ec77184a576d78a46f4c 100644
Binary files a/apps/workflowengine/js/workflowengine.js.map and b/apps/workflowengine/js/workflowengine.js.map differ
diff --git a/core/js/dist/unified-search.js b/core/js/dist/unified-search.js
index 7cd4689d52c7ef847a4a9de05cf8a581c57201ab..5073f0349efbb7d9784b2195851d0b0b5a664521 100644
Binary files a/core/js/dist/unified-search.js and b/core/js/dist/unified-search.js differ
diff --git a/core/js/dist/unified-search.js.map b/core/js/dist/unified-search.js.map
index 18d0e6cb6f7277e84a90d8d72837f3bdc5fdcd86..8eff100478a975675eee4644ce957d42af223f5b 100644
Binary files a/core/js/dist/unified-search.js.map and b/core/js/dist/unified-search.js.map differ
diff --git a/package-lock.json b/package-lock.json
index 7bdd64a6c902cd8b219025e6749821fc383439be..979a1da18e6541d3dec49c37ba86c51efb26465c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1272,9 +1272,9 @@
       }
     },
     "@nextcloud/vue": {
-      "version": "2.6.8",
-      "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-2.6.8.tgz",
-      "integrity": "sha512-9yi9V4gX4Y1uxh2hNxCAlTHaS9zolzAy7x1sowII/WZfxMysF/yIGmEsnYGyz6CZ5eYCzxNUgrU5p/HQ21/09Q==",
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/@nextcloud/vue/-/vue-2.6.9.tgz",
+      "integrity": "sha512-Jx5h9WH+W9Tjz1mAhHq/QpqGMF9XbxpfQIK1DkEMPZ9N9ooLCpphaDN9qmPgOgt68ZGeUfGvJ+HrIfwD0r16Gw==",
       "requires": {
         "@nextcloud/auth": "^1.2.3",
         "@nextcloud/axios": "^1.3.2",
@@ -3432,9 +3432,9 @@
       }
     },
     "emoji-mart-vue-fast": {
-      "version": "7.0.5",
-      "resolved": "https://registry.npmjs.org/emoji-mart-vue-fast/-/emoji-mart-vue-fast-7.0.5.tgz",
-      "integrity": "sha512-+ayg30hhxqqM9oMtN9uUG470hT9gtOdFenByJJBm3XTfzI2QMVJ69euwk+xF55OphLfKZxQG7mnVz13lDOjb3g==",
+      "version": "7.0.6",
+      "resolved": "https://registry.npmjs.org/emoji-mart-vue-fast/-/emoji-mart-vue-fast-7.0.6.tgz",
+      "integrity": "sha512-nvGoIRMhgVYHFBcHJMjjYKS71RopuBRGuO/51DqOcIFreRJAaTvAwmk9eUjI1mwXHY7b/cCarrGi3FBE7Kz37A==",
       "requires": {
         "@babel/polyfill": "7.2.5",
         "@babel/runtime": "7.3.4",
diff --git a/package.json b/package.json
index 44cfb038a58168b9a4d3986c0c41adfcfddfc194..208e40f98bb998624abec42b4e45e7b84be76e74 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
     "@nextcloud/password-confirmation": "^1.0.1",
     "@nextcloud/paths": "^1.1.2",
     "@nextcloud/router": "^1.1.0",
-    "@nextcloud/vue": "^2.6.8",
+    "@nextcloud/vue": "^2.6.9",
     "@nextcloud/vue-dashboard": "^1.0.1",
     "autosize": "^4.0.2",
     "backbone": "^1.4.0",