diff --git a/.eslintrc.js b/.eslintrc.js
index 4a47bcb571742467413e51c9d485e44a8531a90c..0de6fac902a8aa460d393fe64310aec73f4c49ac 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,7 +1,6 @@
 module.exports = {
 	globals: {
 		__webpack_nonce__: true,
-		__webpack_public_path__: true,
 		_: true,
 		$: true,
 		moment: true,
diff --git a/apps/dashboard/lib/Controller/DashboardController.php b/apps/dashboard/lib/Controller/DashboardController.php
index 88baa641b45144ba1d2422c236ed7e18f30511b7..f79f8b992d1620fcd8ffb30ad70de5a7be512f42 100644
--- a/apps/dashboard/lib/Controller/DashboardController.php
+++ b/apps/dashboard/lib/Controller/DashboardController.php
@@ -94,6 +94,8 @@ class DashboardController extends Controller {
 	 */
 	public function index(): TemplateResponse {
 		\OCP\Util::addStyle('dashboard', 'dashboard');
+		\OCP\Util::addScript('dashboard', 'main');
+
 		$this->eventDispatcher->dispatchTyped(new LoadSidebar());
 		if (class_exists(LoadViewer::class)) {
 			$this->eventDispatcher->dispatchTyped(new LoadViewer());
diff --git a/apps/dashboard/src/main.js b/apps/dashboard/src/main.js
index 54c68bf71ee71ba008fde475bb2a637523547423..f209b00baf474571723924619684811b745f777e 100644
--- a/apps/dashboard/src/main.js
+++ b/apps/dashboard/src/main.js
@@ -25,18 +25,19 @@ import App from './App.vue'
 import { translate as t } from '@nextcloud/l10n'
 import VTooltip from '@nextcloud/vue/dist/Directives/Tooltip'
 import { getRequestToken } from '@nextcloud/auth'
-import { generateFilePath } from '@nextcloud/router'
 
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = generateFilePath('dashboard', '', 'js/')
 
 Vue.directive('Tooltip', VTooltip)
 
 Vue.prototype.t = t
 
 // FIXME workaround to make the sidebar work
+if (!window.OCA.Files) {
+	window.OCA.Files = {}
+}
+
 Object.assign(window.OCA.Files, { App: { fileList: { filesClient: OC.Files.getClient() } } }, window.OCA.Files)
 
 const Dashboard = Vue.extend(App)
diff --git a/apps/dashboard/templates/index.php b/apps/dashboard/templates/index.php
index 9e345cdd34a3c552cb2977a0596e277464f0f140..33fb41d3b78c506e9ae47d4150235369e4a5226f 100644
--- a/apps/dashboard/templates/index.php
+++ b/apps/dashboard/templates/index.php
@@ -1,5 +1 @@
-<?php
-	declare(strict_types=1);
-	\OCP\Util::addScript('dashboard', 'dashboard');
-?>
 <div id="app-content-vue"></div>
diff --git a/apps/files/src/main-personal-settings.js b/apps/files/src/main-personal-settings.js
index 4a56e836ecd698fdacc13fac5ac46da1364c8280..af98d3bea4963964c6daafca431fd8ce74dd765f 100644
--- a/apps/files/src/main-personal-settings.js
+++ b/apps/files/src/main-personal-settings.js
@@ -22,39 +22,13 @@
  *
  */
 
-// global t
-
-/*
- * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
 import Vue from 'vue'
 import { getRequestToken } from '@nextcloud/auth'
-import { generateFilePath } from '@nextcloud/router'
 
 import PersonalSettings from './components/PersonalSettings'
 
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = generateFilePath('files', '', 'js/')
 
 Vue.prototype.t = t
 
diff --git a/apps/files_sharing/src/additionalScripts.js b/apps/files_sharing/src/additionalScripts.js
index 6f07f7170caec3d40ac203271069477b9d0721f8..a91a84b5f915cb85384e566c4adc474e7d7444d9 100644
--- a/apps/files_sharing/src/additionalScripts.js
+++ b/apps/files_sharing/src/additionalScripts.js
@@ -24,13 +24,9 @@
 
 import './share'
 import './sharebreadcrumbview'
-
 import './style/sharebreadcrumb.scss'
-
 import './collaborationresourceshandler.js'
 
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = OC.linkTo('files_sharing', 'js/dist/')
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(OC.requestToken)
 
diff --git a/apps/files_sharing/src/collaborationresourceshandler.js b/apps/files_sharing/src/collaborationresourceshandler.js
index 91558add383ed4faad03715d5d8600568378d6eb..cdbd603d4c711e34b68c71aa24210ea6317c6a5f 100644
--- a/apps/files_sharing/src/collaborationresourceshandler.js
+++ b/apps/files_sharing/src/collaborationresourceshandler.js
@@ -21,8 +21,6 @@
  *
  */
 
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = OC.linkTo('files_sharing', 'js/dist/')
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(OC.requestToken)
 
diff --git a/apps/files_sharing/src/files_sharing.js b/apps/files_sharing/src/files_sharing.js
index 1967006dd47edc5c5df506f6349ec92bf06c1307..03ea2c739f76bb7fe39a0c0b503d672c16471f23 100644
--- a/apps/files_sharing/src/files_sharing.js
+++ b/apps/files_sharing/src/files_sharing.js
@@ -23,9 +23,3 @@
 
 import '../js/app'
 import '../js/sharedfilelist'
-
-// eslint-disable-next-line camelcase
-__webpack_nonce__ = btoa(OC.requestToken)
-
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = OC.linkTo('files_sharing', 'js/dist/')
diff --git a/apps/files_sharing/src/personal-settings.js b/apps/files_sharing/src/personal-settings.js
index fb36e022c0dca4e171f48d4df48c060a18fee658..9f27b7bf5a1f50f222a552fef3547c9cf3f27c14 100644
--- a/apps/files_sharing/src/personal-settings.js
+++ b/apps/files_sharing/src/personal-settings.js
@@ -21,39 +21,13 @@
  *
  */
 
-// global t
-
-/*
- * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
 import Vue from 'vue'
 import { getRequestToken } from '@nextcloud/auth'
-import { generateFilePath } from '@nextcloud/router'
 
 import PersonalSettings from './components/PersonalSettings'
 
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = generateFilePath('files', '', 'js/')
 
 Vue.prototype.t = t
 
diff --git a/apps/settings/src/main-apps-users-management.js b/apps/settings/src/main-apps-users-management.js
index f50e98785d7ca73fb5c4ad105ee912f757a905b0..97f23c03f51073da66d40bfb45866f2769723dea 100644
--- a/apps/settings/src/main-apps-users-management.js
+++ b/apps/settings/src/main-apps-users-management.js
@@ -35,15 +35,9 @@ Vue.use(VTooltip, { defaultHtml: false })
 sync(store, router)
 
 // CSP config for webpack dynamic chunk loading
-// eslint-disable-next-line
+// eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(OC.requestToken)
 
-// Correct the root of the app for chunk loading
-// OC.linkTo matches the apps folders
-// OC.generateUrl ensure the index.php (or not)
-// eslint-disable-next-line
-__webpack_public_path__ = OC.linkTo('settings', 'js/')
-
 // bind to window
 Vue.prototype.t = t
 Vue.prototype.n = n
diff --git a/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php b/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php
index 30ebcb89ac836cfa2cfb8195137793e2be712ac0..10a9434835c2098eed1ddb8aa481d3fd6543bc21 100644
--- a/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php
+++ b/apps/theming/lib/Listener/BeforeTemplateRenderedListener.php
@@ -77,6 +77,7 @@ class BeforeTemplateRenderedListener implements IEventListener {
 			]
 		);
 
-		\OCP\Util::addScript('theming', 'theming');
+		// Making sure to inject just after core
+		\OCP\Util::addScript('theming', 'theming', 'core');
 	}
 }
diff --git a/apps/user_status/src/dashboard.js b/apps/user_status/src/dashboard.js
index 8b85b695f778957a8c54f49aea78f0c11ba9c9e8..f419003f34d9ac11fbae0b9e9dbde67bc0c01f02 100644
--- a/apps/user_status/src/dashboard.js
+++ b/apps/user_status/src/dashboard.js
@@ -21,17 +21,13 @@
  */
 
 import Vue from 'vue'
-import { generateFilePath } from '@nextcloud/router'
 import { getRequestToken } from '@nextcloud/auth'
 import { translate, translatePlural } from '@nextcloud/l10n'
 import Dashboard from './views/Dashboard'
 
-// eslint-disable-next-line
+// eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
 
-// eslint-disable-next-line
-__webpack_public_path__ = generateFilePath('user_status', '', 'js/')
-
 Vue.prototype.t = translate
 Vue.prototype.n = translatePlural
 Vue.prototype.OC = OC
diff --git a/apps/user_status/src/menu.js b/apps/user_status/src/menu.js
index be10d700f085228fb3e5fea018c8a6c3cb17c733..3c29f61cc0c0b21aa08b74ecf85c1458fe7a22c6 100644
--- a/apps/user_status/src/menu.js
+++ b/apps/user_status/src/menu.js
@@ -31,12 +31,6 @@ import Avatar from '@nextcloud/vue/dist/Components/Avatar'
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
 
-// Correct the root of the app for chunk loading
-// OC.linkTo matches the apps folders
-// OC.generateUrl ensure the index.php (or not)
-// eslint-disable-next-line
-__webpack_public_path__ = OC.linkTo('user_status', 'js/')
-
 Vue.prototype.t = t
 Vue.prototype.$t = t
 
diff --git a/apps/weather_status/src/weather-status.js b/apps/weather_status/src/weather-status.js
index 0816f62e8dc52aaa8a4d1b61791152457dfef153..4b8b2ab79a47dc6391c0bb2b9ccdfa3aa679086b 100644
--- a/apps/weather_status/src/weather-status.js
+++ b/apps/weather_status/src/weather-status.js
@@ -22,16 +22,11 @@
 
 import Vue from 'vue'
 import { getRequestToken } from '@nextcloud/auth'
-import { generateUrl } from '@nextcloud/router'
 import App from './App'
 
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
 
-// Correct the root of the app for chunk loading
-// eslint-disable-next-line
-__webpack_public_path__ = generateUrl('/apps/weather_status/js/')
-
 Vue.prototype.t = t
 
 document.addEventListener('DOMContentLoaded', function() {
diff --git a/core/src/profile.js b/core/src/profile.js
index f0ff5923a611d1a9c9dd15197b044ec07bb9b651..4e99a11b0e2d8efb71b9aec11c1c68d21dde1f46 100644
--- a/core/src/profile.js
+++ b/core/src/profile.js
@@ -21,7 +21,6 @@
  */
 
 import Vue from 'vue'
-import { generateFilePath } from '@nextcloud/router'
 import { getRequestToken } from '@nextcloud/auth'
 import { translate as t } from '@nextcloud/l10n'
 import VTooltip from 'v-tooltip'
@@ -31,7 +30,6 @@ import logger from './logger'
 import Profile from './views/Profile'
 
 __webpack_nonce__ = btoa(getRequestToken())
-__webpack_public_path__ = generateFilePath('core', '', 'js/')
 
 Vue.use(VTooltip)
 
diff --git a/core/src/recommendedapps.js b/core/src/recommendedapps.js
index 44c424989be30b6195da65093d5ab4109376a808..31d0e5c932c3f790e4048ad7910489a8d312591c 100644
--- a/core/src/recommendedapps.js
+++ b/core/src/recommendedapps.js
@@ -21,7 +21,6 @@
  */
 
 import { getRequestToken } from '@nextcloud/auth'
-import { generateFilePath } from '@nextcloud/router'
 import { translate as t } from '@nextcloud/l10n'
 import Vue from 'vue'
 
@@ -30,8 +29,6 @@ import RecommendedApps from './components/setup/RecommendedApps'
 
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = generateFilePath('core', '', 'js/')
 
 Vue.mixin({
 	methods: {
diff --git a/core/src/unified-search.js b/core/src/unified-search.js
index a799586017b446da10d4877284765566374386da..91db8b34dd0e0e46bf0d0719d12ff5cfb327b2ae 100644
--- a/core/src/unified-search.js
+++ b/core/src/unified-search.js
@@ -20,7 +20,6 @@
  *
  */
 
-import { generateFilePath } from '@nextcloud/router'
 import { getLoggerBuilder } from '@nextcloud/logger'
 import { getRequestToken } from '@nextcloud/auth'
 import { translate as t, translatePlural as n } from '@nextcloud/l10n'
@@ -31,9 +30,6 @@ import UnifiedSearch from './views/UnifiedSearch.vue'
 // eslint-disable-next-line camelcase
 __webpack_nonce__ = btoa(getRequestToken())
 
-// eslint-disable-next-line camelcase
-__webpack_public_path__ = generateFilePath('core', '', 'js/')
-
 const logger = getLoggerBuilder()
 	.setApp('unified-search')
 	.detectUser()
diff --git a/webpack.common.js b/webpack.common.js
index b101456bd5daa71080865e8cfa2413f88b9ef29e..456f971a3aaf4d661a3fcc443be016ad6942909e 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -42,7 +42,8 @@ module.exports = {
 	output: {
 		// Step away from the src folder and extract to the js folder
 		path: path.join(__dirname, 'dist'),
-		publicPath: '/dist/',
+		// Let webpack determine automatically where it's located
+		publicPath: 'auto',
 		filename: '[name].js?v=[contenthash]',
 		chunkFilename: '[name]-[id].js?v=[contenthash]',
 		// Make sure sourcemaps have a proper path and do not
diff --git a/webpack.modules.js b/webpack.modules.js
index e794acf067a3a28befcde6ad2fffce409e83f773..8ada088bab1e0200bd8c091d1d2a80239025b493 100644
--- a/webpack.modules.js
+++ b/webpack.modules.js
@@ -43,7 +43,7 @@ module.exports = {
 		systemtags: path.resolve(__dirname, 'core/src', 'systemtags/merged-systemtags.js'),
 	},
 	dashboard: {
-		'dashboard-main': path.join(__dirname, 'apps/dashboard/src', 'main.js'),
+		main: path.join(__dirname, 'apps/dashboard/src', 'main.js'),
 	},
 	dav: {
 		'settings-admin-caldav': path.join(__dirname, 'apps/dav/src', 'settings.js'),