> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# Static assets

Rslib supports importing static assets, including images, fonts, media, and other file types.

## Asset formats

Rslib supports these formats by default:

- **Images**: png, jpg, jpeg, gif, svg, bmp, webp, ico, apng, avif, tif, tiff, jfif, pjpeg, pjp, cur, jxl.
- **Fonts**: woff, woff2, eot, ttf, otf, ttc.
- **Audio**: mp3, wav, flac, aac, m4a, opus.
- **Video**: mp4, webm, ogg, mov.
- **Other**: webmanifest, pdf, txt, vtt.

In addition to the static asset types listed above, when [output.target](/config/rsbuild/output.md#outputtarget) is `'node'`, Rslib also supports importing Node.js [addons](https://nodejs.org/api/addons.html) in JavaScript files.

To import assets in other formats, refer to [Extend Asset Types](#extend-asset-types).

## Import assets in JavaScript file

### `import` imports

In JavaScript files, you can directly import static assets with relative paths through `import`:

```tsx
// Import the logo.png image in the 'src/assets' directory
import logo from './assets/logo.png';

console.log(logo); // "/static/image/logo.png"

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

Import with **alias** is also available:

```tsx
import logo from '@/assets/logo.png';

console.log(logo); // "/static/image/logo.png"

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

When the [format](/config/lib/format.md) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and transforms the source file into a JavaScript file and a static asset file that is emitted according to [output.distPath](/config/rsbuild/output.md#outputdistpath) by default with preserving the `import` or `require` statements for static assets.

The following is an example of usage, assuming the source code is as follows:


**src/index.ts**

```tsx
import logo from './assets/logo.svg';

console.log(logo);
```


**src/assets/logo.svg**

![](https://assets.rspack.rs/rslib/rslib-logo.svg)

Based on the configuration in the [output structure](/guide/basic/output-structure.md) in the configuration file, the following outputs will be emitted:


**bundle**


**dist/index.mjs**

```tsx
import logo_namespaceObject from './static/svg/logo.svg';

console.log(logo_namespaceObject);
```


**dist/static/svg/logo.svg**

![](https://assets.rspack.rs/rslib/rslib-logo.svg)


**bundleless**


**dist/index.mjs**

```tsx
import logo from './assets/logo.mjs';

console.log(logo);
```


**dist/assets/logo.mjs**

```tsx
import logo_namespaceObject from '../static/svg/logo.svg';
export { logo_namespaceObject as default };
```


**dist/static/svg/logo.svg**

![](https://assets.rspack.rs/rslib/rslib-logo.svg)


### `new URL` imports

:::note

When referencing static assets with `new URL()`, only ESM output is supported, so [format](/config/lib/format.md) must be set to `'esm'` (the default).

:::

You can also reference static assets by using JavaScript's native [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) together with [import.meta.url](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta):

```ts title="src/index.ts"
const logo = new URL('./assets/logo.svg', import.meta.url);
```

After the build, the path in `new URL()` points to the emitted asset file, producing the following output:


**dist/index.js**

```js
const logo = new URL('./static/svg/logo.svg', import.meta.url);
```


**dist/static/svg/logo.svg**

![](https://assets.rspack.rs/rslib/rslib-logo.svg)

Files such as `.js`, `.ts`, `.css`, and `.scss` referenced through `new URL()` are also treated as URL assets. They bypass the relevant built-in loaders, and their original contents are emitted as assets.

:::note

When [bundle](/config/lib/bundle.md) is `false`, the default entry is the `src/**` glob pattern, which also matches static asset files under `src`. Assets referenced through `new URL()` need to be excluded from [source.entry](/config/rsbuild/source.md#sourceentry).

```ts title="rslib.config.ts"
export default {
  lib: [
    {
      bundle: false,
      source: {
        entry: {
          index: ['src/**', '!src/assets/logo.svg'],
        },
      },
    },
  ],
};
```

:::

#### Skip `new URL()` processing

If you do not want `new URL()` expressions to be parsed as URL assets, choose one of the following approaches based on the required scope.

##### Disable the URL parser

When building ESM output, Rslib processes `new URL()` expressions in JavaScript and TypeScript files with the URL parser's [`'new-url-relative'`](https://rspack.rs/config/module-parser#javascripturl) mode by default.

To preserve the original `new URL()` expressions without having Rslib emit the corresponding assets, set the URL parser to `false` through [tools.bundlerChain](/config/rsbuild/tools.md#toolsbundlerchain):

```ts title="rslib.config.ts"
import { defineConfig } from '@rslib/core';

export default defineConfig({
  tools: {
    bundlerChain(chain) {
      chain.module.rule('rslib:new-url').parser({
        url: false,
      });
    },
  },
});
```

After the parser is disabled, the `new URL()` expression is preserved unchanged, and Rslib does not emit the referenced file:

```js title="dist/index.js"
const logo = new URL('./assets/logo.svg', import.meta.url);
```

The output retains the standard `new URL(path, import.meta.url)` form. If the referenced asset needs to be published with the output, we recommend copying it to the output directory through [output.copy](/config/rsbuild/output.md#outputcopy) or a similar method and ensuring that its output path matches the relative path in `new URL()`. This allows the asset to be located correctly whether the output is processed by a downstream bundler or run directly in Node.js.

##### Ignore a specific reference

To skip processing for a specific `new URL()` expression, add the [rspackIgnore](https://rspack.rs/api/runtime-api/module-methods#rspackignore) comment before its first argument. The output then preserves the standard `new URL(path, import.meta.url)` expression:

```ts title="src/index.ts"
const logo = new URL(
  /* rspackIgnore: true */ './assets/logo.svg',
  import.meta.url,
);
```

## Import assets in CSS file

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

```css title="src/index.css"
.logo {
  background-image: url('./assets/logo.png');
}
```

Import with **alias** are also supported:

```css title="src/index.css"
.logo {
  background-image: url('@/assets/logo.png');
}
```

When the [format](/config/lib/format.md) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and preserves relative reference paths in CSS outputs by default via setting [output.assetPrefix](/config/rsbuild/output.md#outputassetprefix) to `"auto"`.

The following is an example of usage, assuming the source code is as follows:


**src/index.css**

```css
.logo {
  background-image: url('./assets/logo.png');
}
```


**src/assets/logo.png**

![](https://assets.rspack.rs/rslib/rslib-logo-192x192.png)

The following output will be emitted:


**dist/index.css**

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


**dist/static/image/logo.png**

![](https://assets.rspack.rs/rslib/rslib-logo-192x192.png)

***

### Ignore some assets imported in CSS

If you need to import a static asset with an absolute path in a CSS file:

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

By default, the built-in `css-loader` in Rslib 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`](/config/rsbuild/tools.md#toolscssloader) to filter out the specified paths. The filtered paths are preserved as they are in the code.

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

## Inline static assets

When the [format](/config/lib/format.md) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and sets [output.dataUriLimit](/config/rsbuild/output.md#outputdataurilimit) to `0` by default to not inline any static assets.

## Build output directory

Once static assets are imported, they will automatically be output to the build output directory. You can:

- Modify the filename of the outputs through [output.filename](/config/rsbuild/output.md#outputfilename). For example, add a hash value to the filename of the outputs, which is usually used when there are files with the same name to avoid filename conflicts.

```ts title="rslib.config.ts"
export default {
  output: {
    filename: {
      svg: '[name].[contenthash:10].svg',
      font: '[name].[contenthash:10][ext]',
      image: '[name].[contenthash:10][ext]',
      media: '[name].[contenthash:10][ext]',
      assets: '[name].[contenthash:10][ext]',
    },
  },
};
```

- Change the output path of the outputs through [output.distPath](/config/rsbuild/output.md#outputdistpath). For example, emit static assets output to the `dist/resource` directory.

```ts title="rslib.config.ts"
export default {
  output: {
    distPath: {
      svg: 'resource/svg',
      font: 'resource/font',
      image: 'resource/image',
      media: 'resource/media',
      assets: 'resource/assets',
    },
  },
};
```

## 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, use one of the following methods:

- Method 1: If the `@rslib/core` package is installed, you can add the [preset types](/guide/basic/typescript.md#preset-types) provided by `@rslib/core` to `tsconfig.json`:

```json title="tsconfig.json"
{
  "compilerOptions": {
    "types": ["@rslib/core/types"]
  }
}
```

- Method 2: Manually add the required type declarations:

```ts title="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 Rslib cannot meet your requirements, you can extend additional static asset types in the following ways.

### Use `source.assetsInclude`

By using the [source.assetsInclude](/config/rsbuild/source.md#sourceassetsinclude) config, you can specify additional file types to be treated as static assets.

```ts title="rslib.config.ts"
export default {
  source: {
    assetsInclude: /\.gltf$/,
  },
};
```

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

```js
import myFile from './static/model.gltf';

console.log(myFile); // "/static/assets/model.gltf"
```

### Use `tools.rspack`

You can modify the built-in Rspack configuration and add custom static assets handling rules via [tools.rspack](/config/rsbuild/tools.md#toolsrspack).

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

```ts title="rslib.config.ts"
export default {
  tools: {
    rspack(config, { addRules }) {
      addRules([
        {
          test: /\.gltf$/,
          // Convert assets to separate files and keep import statements
          type: 'asset/resource',
          generator: {
            importMode: 'preserve',
          },
        },
      ]);
    },
  },
};
```

For more information about asset modules, please refer to [Rspack - Asset modules](https://rspack.rs/guide/features/asset-module).
