For AI agents: the complete documentation index is available at https://rspack.rs/llms.txt, the full documentation bundle is available at https://rspack.rs/llms-full.txt, and this page is available as Markdown at https://rspack.rs/guide/features/asset-base-path.md.
close

Asset base path

Rspack provides the output.publicPath option, which sets the base URL path prefix for bundled static assets (such as JS, CSS, images, etc.).

Use cases

Imagine the following scenarios:

  • Your static assets need to be deployed to a CDN
  • Your web application is not deployed under the root path of the domain
  • You need to use different assets paths for different environments (development, testing, or production)

In these scenarios, configuring output.publicPath can help you load static assets correctly.

Basic example

Set output.publicPath to /, then the assets path will be relative to the root path.

rspack.config.mjs
export default {
  output: {
    publicPath: '/',
  },
};

With this configuration, the assets access path is http://[domain]/, for example http://localhost:8080/main.js.

Subdirectory

If your application needs to be deployed under a subdirectory, you can set output.publicPath to the corresponding subdirectory path:

rspack.config.mjs
export default {
  output: {
    publicPath: '/assets/',
  },
};

With this configuration, all assets will be loaded from the /assets/ path, for example http://localhost:8080/assets/main.js.

Tip
  • The value of output.publicPath usually ends with /.
  • With a relative output.publicPath, such as ./assets/ or an empty string, asset URLs depend on the base used to resolve them. In browsers, this is often the page URL, so nested page paths or an HTML <base> element can affect where assets load from. See Base URI for how Rspack resolves asset URLs.

Use CDN

When deploying static assets using CDN, you can set output.publicPath based on the environment variable, and set it to the CDN URL prefix during the production build.

rspack.config.mjs
const isProd = process.env.NODE_ENV === 'production';

export default {
  output: {
    publicPath: isProd ? 'https://cdn.example.com/' : '/',
  },
};

With this configuration:

  • In the development mode, the assets access path is http://[domain]/, for example http://localhost:8080/main.js.
  • In the production mode, the assets access path is https://cdn.example.com/, for example https://cdn.example.com/main.[hash].js.

Dynamically set publicPath

You can set publicPath dynamically using import.meta.rspackPublicPath in your JavaScript code.

The import.meta.rspackPublicPath will override the output.publicPath in the Rspack config, but it will only take effect for dynamically loaded assets, not for assets loaded via <script src="...">.

First create a publicPath.js:

publicPath.js
import.meta.rspackPublicPath =
  location.hostname === 'foo.com'
    ? 'https://cdn1.com/assets/'
    : 'https://cdn2.com/assets/';

Then import it into the first line of the entry file to ensure that publicPath is set before async assets are loaded:

entry.js
import './publicPath.js';
import './others.js';

Automatic publicPath

There are chances that you don't know what the publicPath will be in advance, and Rspack can automatically calculate the publicPath value by parsing some variables like import.meta.url, document.currentScript, script.src or self.location.

What you need is to set output.publicPath to 'auto':

rspack.config.mjs
export default {
  output: {
    // this is the default value when `target` is `'web'` or `'webworker'`
    publicPath: 'auto',
  },
};

If your application reports Automatic publicPath is not supported in this browser, see Automatic publicPath cannot be determined.

Base URI

publicPath sets the prefix of an asset URL. If the resulting URL is relative, a base URI is needed to determine its absolute address. For example, using https://example.com/app/index.html as the base URI:

Generated asset URLResolved URL
assets/logo.pnghttps://example.com/app/assets/logo.png
/assets/logo.pnghttps://example.com/assets/logo.png
https://cdn.example.com/logo.pnghttps://cdn.example.com/logo.png (unchanged)

A relative path without a leading / resolves against the base URI's directory. A path starting with / resolves from the root of that site. Absolute URLs are unaffected by the base URI.

When you reference an asset with new URL('./logo.png', import.meta.url), Rspack resolves the emitted asset's URL against this base URI by default. The same applies to Workers created with new Worker(new URL('./worker.js', import.meta.url)).

URLs in HTML <script> and <link> elements are resolved by the browser, independently of Rspack's base URI setting.

Default base URI

You usually do not need to set the base URI yourself. In typical configurations:

  • Browsers use the page URL, or the address specified by an HTML <base> element if one is present.
  • Node.js uses a file: URL based on the output location.

Browser builds default to publicPath: 'auto', which typically produces absolute asset URLs based on the bundle's location. These URLs do not need a base URI. Node.js builds default to publicPath: '', so the resulting relative asset paths resolve against the file: URL described above.

To read the current value, use import.meta.rspackBaseUri:

const baseUri = import.meta.rspackBaseUri;
console.log(baseUri);

To resolve relative paths supplied at runtime, you can pass this value as the second argument to new URL(). This resolves the URL without telling Rspack to bundle the referenced file. To bundle an asset, use new URL('./logo.png', import.meta.url).

Overriding the base URI

Configuring publicPath is usually enough to change where assets are hosted. If you need a different base for resolving relative asset URLs, you can set it in either of these ways:

  • If the address is known at build time, set entry.baseUri to configure the entry's initial base URI.
  • If the address is only known at runtime, assign to import.meta.rspackBaseUri before creating asset URLs.

For example, this configuration uses publicPath: '' to generate relative image URLs, leaving the base URI to determine their absolute addresses:

rspack.config.mjs
export default {
  output: {
    publicPath: '',
    assetModuleFilename: 'assets/[name][ext]',
  },
  module: {
    rules: [{ test: /\.png$/, type: 'asset/resource' }],
  },
};

Then set the base URI to the deployment directory before creating the image URL:

src/index.js
// Use a trailing / for directories.
import.meta.rspackBaseUri = 'https://example.com/app/';

const logoUrl = new URL('./logo.png', import.meta.url);
console.log(logoUrl.href); // https://example.com/app/assets/logo.png

Changing the base URI only affects URLs created afterward that use it; existing URL objects are not updated.

If imported modules create asset URLs during initialization, set the base URI in a separate setup module and ensure that this module runs first.