Fixing Relative Asset Paths and CSS Background URLs After Vue Build

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.

Tags: vue webpack relative-paths assets css-background

Posted on Sat, 09 May 2026 00:50:36 +0000 by miniu