When a Vue CLI 2 project is bundled, the default configuration assumes the generated dist folder will be served from the web root. If the app is deployed to a sub-folder, all relative links break. Two separate fixes are required: one for JavaScript-imported assets and another for CSS url() references.
1. Adjust the base public path
Open config/index.js and locate the build section. Change the value that webpack uses as the base for every asset URL:
build: {
// …
assetsPublicPath: './', // was '/'
// …
}
This single dot tells webpack that every file emitted to dist/static/… should be referenced relative to the HTML file itself, so index.html can live in any folder without 404s.
2. Correct CSS background-image URLs
Even with the step above, CSS files have a different context. When extract-text-webpack-plugin pulls all style into dist/static/css/app.[hash].css, relative url() declarations are resolved from that CSS file, not from the HTML. The result is a extra static/css/ segment in the path:
WRONG …/dist/static/css/static/img/logo.png
RIGHT …/dist/static/img/logo.png
Override the plugin’s public-path only for extracted CSS. Edit build/utils.js:
const isExtract = options.extract
if (isExtract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath: '../../' // walk back to dist root
})
} else {
return ['vue-style-loader'].concat(loaders)
}
../../ walks two directories up from static/css/ to the root of dist, aligning the CSS-relative URLs with the actual image locations.
After both changes, run:
npm run build
The generated bundle now works whether it is deployed at /, /some/nested/path/, or opened directly from the file system.