Import Static Assets

Rsbuild supports import static assets, including images, fonts, audio and video.

What is Static Assets

Static assets are files that are part of a web application and do not change, even when the application is being used. Examples of static assets include images, fonts, medias, stylesheets, and JavaScript files. These assets are typically stored on a web server or CDN, and delivered to the user's web browser when the Web application is accessed. Because they do not change, static assets can be cached by the browser, which helps to improve the performance of the Web application.

Assets Format

The following are the formats supported by Rsbuild by default:

  • images: png, jpg, jpeg, gif, svg, bmp, webp, ico, apng, avif, tif, tiff, jfif, pjpeg, pjp.
  • fonts: woff, woff2, eot, ttf, otf, ttc.
  • audio: mp3, wav, flac, aac, m4a, opus.
  • video: mp4, webm, ogg, mov.

If you need to import assets in other formats, please refer to Extend Asset Types.

SVG images

SVG image is a special case. Rsbuild support convert SVG to React components, so SVG is processed separately. For details, see SVGR Plugin.

Import Assets in JS file

In JS files, you can import static assets with relative paths:

// Import the logo.png image in the static directory
import logo from './static/logo.png';

console.log(logo); // "/static/logo.[hash].png"

export default = () => <img src={logo} />;

Import with alias is also available:

import logo from '@/static/logo.png';

console.log(logo); // "/static/logo.[hash].png"

export default = () => <img src={logo} />;

URL assets

Rsbuild supports using JavaScript's native URL and import.meta.url to import static assets.

const logo = new URL('./static/logo.png', import.meta.url).href;

console.log(logo); // "/static/logo.[hash].png"

export default = () => <img src={logo} />;

If you use new URL() to reference .js or .ts files, they will be treated as URL assets and will not be processed by Rsbuild's built-in swc-loader.

// foo.ts will remain the original content and be output to the dist directory
const fooTs = new URL('./foo.ts', import.meta.url).href;

console.log(fooTs); // "/static/foo.[hash].ts"

Similarly, when using new URL() to reference .css or .scss files, they will be treated as URL assets and will not be processed by Rsbuild's built-in CSS loaders.

// foo.css will remain the original content and be output to the dist directory
const fooCss = new URL('./foo.css', import.meta.url).href;

console.log(fooCss); // "/static/foo.[hash].css"

Import Assets in CSS file

In CSS files, you can reference static assets in relative paths:

.logo {
  background-image: url('../static/logo.png');
}

Import with alias are also supported:

.logo {
  background-image: url('@/static/logo.png');
}

If you want to reference static assets in absolute paths in CSS files:

@font-face {
  font-family: DingTalk;
  src: url('/image/font/foo.ttf');
}

By default, the built-in css-loader in Rsbuild will resolve absolute paths in url() and look for the specified modules. If you want to skip resolving absolute paths, you can configure tools.cssLoader to filter out the specified paths. The filtered paths are left as they are in the code.

export default {
  tools: {
    cssLoader: {
      url: {
        filter: (url) => {
          if (/\/image\/font/.test(url)) {
            return false;
          }
          return true;
        },
      },
    },
  },
};

Import Results

The result of importing static assets depends on the file size:

  • When the file size is greater than 4KiB, a URL will be returned, and the file will be output to the dist directory.
  • When the file size is less than 4KiB, it will be automatically inlined to Base64 format.
import largeImage from './static/largeImage.png';
import smallImage from './static/smallImage.png';

console.log(largeImage); // "/static/largeImage.[hash].png"
console.log(smallImage); // "data:image/png;base64,iVBORw0KGgo..."

For a more detailed introduction to asset inlining, please refer to the Static Asset Inlining chapter.

Output Files

When static assets are imported, they will be output to the dist directory. You can:

Please read Output Files for details.

URL Prefix

The URL returned after importing a asset will automatically include the path prefix:

For example, you can set output.assetPrefix to https://example.com:

import logo from './static/logo.png';

console.log(logo); // "https://example.com/static/logo.[hash].png"

Public Folder

The public folder at the project root can be used to place some static assets. These assets will not be built by Rsbuild and can be directly referenced via URL.

  • When you start the dev server, these assets will be served under the root server.base path, default /.
  • When you perform a production build, these assets will be copied to the dist directory.

For example, you can place files such as robots.txt, manifest.json, or favicon.ico in the public folder.

How to reference

You can reference files in the public directory via a URL.

For example, in an HTML template, the ./public/favicon.ico file can be referenced as /favicon.ico, BASE_URL is the base path of the server.

index.html
<link rel="icon" href="<%= process.env.BASE_URL %>/favicon.ico" />

Notes

Here are some notes on using the public folder:

  • When referencing assets in the public folder via URL, please use absolute paths instead of relative paths to ensure that the assets can be accessed correctly after deployment.
src/index.html
<!-- Wrong -->
<link rel="icon" href="../public/favicon.ico" />

<!-- Correct -->
<link rel="icon" href="/favicon.ico" />
  • Please avoid importing files from the public directory into the source code. The correct approach is to reference them by URL. You can place static assets imported into the source code in the /src/assets directory.
src/index.js
// Wrong
import logo from '../public/logo.png';

// Correct
import logo from './assets/logo.png';
  • During the production build, the files in public folder will be copied to the output folder (default is dist). Please be careful to avoid name conflicts with the output files. When files in the public folder have the same name as outputs, the outputs have higher priority and will overwrite the files with the same name in the public folder. This feature can be disabled by setting server.publicDir.copyOnBuild to false.

Custom Behavior

Rsbuild provides the server.publicDir option which can be used to customize the name and behavior of the public folder, as well as to disable it.

rsbuild.config.ts
export default {
  server: {
    publicDir: false,
  },
};

Type Declaration

When you import static assets in TypeScript code, TypeScript may prompt that the module is missing a type definition:

TS2307: Cannot find module './logo.png' or its corresponding type declarations.

To fix this, you need to add a type declaration file for the static assets, please create a src/env.d.ts file, and add the corresponding type declaration.

  • Method 1: If the @rsbuild/core package is installed, you can reference the preset types provided by @rsbuild/core:
/// <reference types="@rsbuild/core/types" />
  • Method 2: Manually add the required type declarations:
src/env.d.ts
// Taking png images as an example
declare module '*.png' {
  const content: string;
  export default content;
}

After adding the type declaration, if the type error still exists, you can try to restart the current IDE, or adjust the directory where env.d.ts is located, making sure the TypeScript can correctly identify the type definition.

Extend Asset Types

If the built-in asset types in Rsbuild cannot meet your requirements, you can extend additional static asset types in the following ways.

Use source.assetsInclude

By using the source.assetsInclude config, you can specify additional file types to be treated as static assets.

rsbuild.config.ts
export default {
  source: {
    assetsInclude: /\.pdf$/,
  },
};

After adding the above configuration, you can import *.pdf files in your code, for example:

import myFile from './static/myFile.pdf';

console.log(myFile); // "/static/myFile.[hash].pdf"

Use tools.rspack

You can modify the built-in Rspack configuration and add custom static assets handling rules via tools.rspack.

For example, to treat *.pdf files as assets and output them to the dist directory, you can add the following configuration:

rsbuild.config.ts
export default {
  tools: {
    rspack(config, { addRules }) {
      addRules([
        {
          test: /\.pdf$/,
          // converts asset to a separate file and exports the URL address.
          type: 'asset/resource',
        },
      ]);
    },
  },
};

For more information about asset modules, please refer to Rspack - Asset modules.

Extended static asset types will be affected by the following configurations:

Custom Rules

In some scenarios, you may need to bypass the built-in assets processing rules of Rsbuild and add some custom rules.

Taking PNG image as an example, you need to:

  1. Modify the built-in Rspack config via tools.bundlerChain to exclude .png files using the exclude method.
  2. Add custom asset processing rules via tools.rspack.
rsbuild.config.ts
export default {
  tools: {
    bundlerChain(chain, { CHAIN_ID }) {
      chain.module
        // Use `CHAIN_ID.RULE.IMAGE` to locate the built-in image rule
        .rule(CHAIN_ID.RULE.IMAGE)
        .exclude.add(/\.png$/);
    },
    rspack(config, { addRules }) {
      addRules([
        {
          test: /\.png$/,
          // Add a custom loader to handle png images
          loader: 'custom-png-loader',
        },
      ]);
    },
  },
};

Image Format

When using image assets, you can choose a appropriate image format according to the pros and cons in the table below.

Format Pros Cons Scenarios
PNG Lossless compression, no loss of picture details, no distortion, support for translucency Not suitable for pictures with complex color tables Suitable for pictures with few colors and well-defined borders, suitable for logos, icons, transparent images and other scenes
JPG Rich colors Lossy compression, which will cause image distortion, does not support transparency Suitable for pictures with a large number of colors, gradients, and overly complex pictures, suitable for portrait photos, landscapes and other scenes
WebP Supports both lossy and lossless compression, supports transparency, and is much smaller than PNG and JPG iOS compatibility is not good Pixel images of almost any scene, and the hosting environment that supports WebP, should prefer WebP image format
SVG Lossless format, no distortion, supports transparency Not suitable for complex graphics Suitable for vector graphics, suitable for icons