On this page

output.publicPath tells webpack the base URL that the browser should use when it requests the files your build emits. Every file written to output.path is referenced from output.publicPath at runtime: the chunks created by code splitting, and any other asset in your dependency graph such as images and fonts.

Getting this wrong is one of the more confusing failure modes in webpack, because the build succeeds and only the browser notices: the page loads, then a chunk or an image 404s from a path that looks almost right.

The most common reason to change the public path is that the same code is served from different places in different environments. During development, assets might sit next to the page in an assets/ folder; in production, they are served from a CDN.

An environment variable handles both cases with one configuration. Say the variable is ASSET_PATH:

import webpack from 'webpack';

// Try the environment variable, otherwise use root.
const ASSET_PATH = process.env.ASSET_PATH || '/';

export default {
  output: {
    publicPath: ASSET_PATH,
  },

  plugins: [
    // Make the same value readable from application code.
    new webpack.DefinePlugin({
      'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
    }),
  ],
};

See the environment variables guide for the different ways to feed a value into a configuration.

Sometimes the base URL is not knowable at build time at all: it depends on the tenant, the deployment, or a value the server injects into the page. webpack exposes a free variable, __webpack_public_path__, that overrides output.publicPath for the rest of the run:

Because the DefinePlugin entry above replaces process.env.ASSET_PATH at build time, this works without any runtime lookup.

Warning

The assignment has to run before webpack loads anything else. In an ES module, all import statements are evaluated before the module body, so an assignment written at the top of your entry file still runs too late. Move it into its own module and import that module first.

import './public-path';
import './app';

If you don't know the public path in advance and don't want to thread one through, set it to 'auto' and webpack derives it at runtime from whatever the current environment exposes: import.meta.url, document.currentScript, script.src, or self.location.

export default {
  output: {
    publicPath: 'auto',
  },
};

This is a good default for a library or a micro-frontend that gets dropped into a host page you don't control, since the bundle locates itself instead of trusting a configured path.

SituationUse
Assets are served from a fixed, known URL per environmentoutput.publicPath from an environment variable
The base URL is only known once the page is running__webpack_public_path__ in a dedicated first import
The bundle is embedded in a host you don't controloutput.publicPath: 'auto'
A single asset needs a different base than everything elsepublicPath on the asset rule