Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.webpack.js.org/llms.txt

Use this file to discover all available pages before exploring further.

Asset modules allow you to use asset files (fonts, icons, images, etc.) without configuring additional loaders.

Asset Module Types

Webpack 5 provides four asset module types:
TypeDescriptionOld Equivalent
asset/resourceEmits file and exports URLfile-loader
asset/inlineExports data URIurl-loader
asset/sourceExports source coderaw-loader
assetAuto-chooses between resource and inlineurl-loader with limit
Asset modules are built into webpack 5. No need to install additional loaders.

Basic Usage

1

Configure asset module types

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg|gif|svg)$/,
        type: 'asset/resource'
      }
    ]
  }
};
2

Import assets in your code

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

const img = document.createElement('img');
img.src = logo;
document.body.appendChild(img);
3

Configure output location

module.exports = {
  output: {
    assetModuleFilename: 'assets/[hash][ext][query]'
  }
};

asset/resource

Emits files to the output directory and returns the URL:
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg|gif)$/,
        type: 'asset/resource'
      }
    ]
  },
  output: {
    assetModuleFilename: 'images/[hash][ext][query]'
  }
};
Usage:
import imageUrl from './photo.jpg';
// imageUrl is: 'images/a1b2c3d4.jpg'
Use asset/resource for large images, videos, and other files that should be loaded separately.

asset/inline

Inlines assets as data URIs:
module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        type: 'asset/inline'
      }
    ]
  }
};
Usage:
import svgData from './icon.svg';
// svgData is: 'data:image/svg+xml;base64,...'
Inlining large files increases bundle size. Only inline small assets (< 8-10 KB).

asset/source

Imports the raw source code of the asset:
module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        type: 'asset/source'
      }
    ]
  }
};
Usage:
import textContent from './data.txt';
// textContent is the text file content as a string
console.log(textContent);

asset (Automatic)

Automatically chooses between inline and resource based on file size:
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif|svg)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024 // 8kb
          }
        }
      }
    ]
  }
};
Behavior:
  • Files < 8 KB: Inlined as data URI
  • Files ≥ 8 KB: Emitted as separate files
The asset type is the most versatile. It optimizes automatically based on file size.

Custom Output Filenames

Global Configuration

module.exports = {
  output: {
    assetModuleFilename: 'assets/[name]-[hash][ext][query]'
  }
};

Per-Rule Configuration

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg)$/,
        type: 'asset/resource',
        generator: {
          filename: 'images/[hash][ext][query]'
        }
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[name][ext]'
        }
      }
    ]
  }
};

Filename Placeholders

PlaceholderDescription
[name]Original filename
[hash]Content hash
[ext]Extension with dot
[query]Query string
[path]Original path
[contenthash]Content hash (alias)
Example:
generator: {
  filename: 'assets/[path][name]-[hash:8][ext]'
}

Common Asset Types

Images

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg|gif|webp)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024
          }
        },
        generator: {
          filename: 'images/[hash][ext][query]'
        }
      }
    ]
  }
};

SVG

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        type: 'asset/inline',
        generator: {
          dataUrl: content => {
            content = content.toString();
            return `data:image/svg+xml,${encodeURIComponent(content)}`;
          }
        }
      }
    ]
  }
};

Fonts

module.exports = {
  module: {
    rules: [
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[name][ext]'
        }
      }
    ]
  }
};
Usage in CSS:
@font-face {
  font-family: 'MyFont';
  src: url('./fonts/myfont.woff2') format('woff2');
}

Data Files

module.exports = {
  module: {
    rules: [
      {
        test: /\.(json|xml|csv)$/,
        type: 'asset/source'
      }
    ]
  }
};

Public Path

Set the base path for assets in production:
module.exports = {
  output: {
    publicPath: 'https://cdn.example.com/',
    assetModuleFilename: 'assets/[hash][ext]'
  }
};
Result:
import logo from './logo.png';
// logo is: 'https://cdn.example.com/assets/a1b2c3d4.png'
The publicPath is prepended to all asset URLs. Use it when serving assets from a CDN.

Custom Data URL

Customize how data URIs are generated:
module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        type: 'asset/inline',
        generator: {
          dataUrl: content => {
            const svgContent = content.toString();
            // Optimize or transform SVG
            return `data:image/svg+xml;utf8,${encodeURIComponent(svgContent)}`;
          }
        }
      }
    ]
  }
};

Migration from Loaders

From file-loader

Before:
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: ['file-loader']
      }
    ]
  }
};
After:
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        type: 'asset/resource'
      }
    ]
  }
};

From url-loader

Before:
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ]
  }
};
After:
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8192
          }
        }
      }
    ]
  }
};

From raw-loader

Before:
module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: 'raw-loader'
      }
    ]
  }
};
After:
module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        type: 'asset/source'
      }
    ]
  }
};
Asset modules are simpler and faster than the old loader approach. Migrate when upgrading to webpack 5.

Complete Example

const path = require('path');

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[contenthash].js',
    assetModuleFilename: 'assets/[hash][ext][query]',
    publicPath: '/'
  },
  module: {
    rules: [
      // Images - auto inline if < 8kb
      {
        test: /\.(png|jpg|jpeg|gif|webp)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024
          }
        },
        generator: {
          filename: 'images/[hash][ext][query]'
        }
      },
      // SVG - inline as data URI
      {
        test: /\.svg$/,
        type: 'asset/inline'
      },
      // Fonts - always separate files
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[name][ext]'
        }
      },
      // Text/data files - raw content
      {
        test: /\.(txt|md)$/,
        type: 'asset/source'
      }
    ]
  }
};