Skip to main content
url-loader is deprecated in webpack 5. Use Asset Modules with type: 'asset' or type: 'asset/inline' instead.

Overview

url-loader works like file-loader, but can return a data URI if the file is smaller than a specified limit. This was useful for reducing HTTP requests by inlining small files.

Migration to Asset Modules

Webpack 5 Asset Modules provide the same functionality with better performance and no external dependencies.
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192,
              name: 'images/[name].[hash:8].[ext]'
            }
          }
        ]
      }
    ]
  }
};

Installation (Legacy)

Only install if you’re maintaining a legacy webpack 4 project. For webpack 5, use Asset Modules.
npm install -D url-loader file-loader
url-loader requires file-loader as a peer dependency for files that exceed the size limit.

Basic Usage (Legacy)

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ]
  }
};

How It Works

  1. File size is checked against the limit option
  2. If size < limit: File is converted to base64 data URI
  3. If size >= limit: Falls back to file-loader behavior

Options (Legacy)

limit

Maximum file size (in bytes) to inline:
{
  loader: 'url-loader',
  options: {
    limit: 8192 // 8kb
  }
}
Files smaller than limit are inlined. Larger files are emitted as separate files.

mimetype

Specify MIME type:
{
  loader: 'url-loader',
  options: {
    limit: 8192,
    mimetype: 'image/png'
  }
}

encoding

Specify encoding (default: base64):
{
  loader: 'url-loader',
  options: {
    limit: 8192,
    encoding: 'base64'
  }
}

fallback

Specify fallback loader (default: file-loader):
{
  loader: 'url-loader',
  options: {
    limit: 8192,
    fallback: 'file-loader'
  }
}

File-loader Options

Pass options to file-loader for files exceeding limit:
{
  loader: 'url-loader',
  options: {
    limit: 8192,
    name: '[name].[hash:8].[ext]',
    outputPath: 'images/',
    publicPath: '/assets/images/'
  }
}

Common Patterns (Legacy)

Images with Size Limit

{
  test: /\.(png|jpg|gif)$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 8192,
        name: 'images/[name].[contenthash:8].[ext]'
      }
    }
  ]
}

SVG Icons

{
  test: /\.svg$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 10000,
        mimetype: 'image/svg+xml'
      }
    }
  ]
}

Fonts

{
  test: /\.(woff|woff2)$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 50000,
        mimetype: 'application/font-woff',
        name: 'fonts/[name].[ext]'
      }
    }
  ]
}

Complete Migration Guide

Inline Small Images

{
  test: /\.(png|jpg|gif)$/i,
  loader: 'url-loader',
  options: {
    limit: 8192
  }
}

Always Inline

{
  test: /\.svg$/i,
  loader: 'url-loader',
  options: {
    limit: Infinity
  }
}

Custom MIME Type

{
  test: /\.svg$/i,
  loader: 'url-loader',
  options: {
    limit: 10000,
    mimetype: 'image/svg+xml'
  }
}

With Output Path

{
  test: /\.(png|jpg)$/i,
  loader: 'url-loader',
  options: {
    limit: 8192,
    name: '[name].[hash:8].[ext]',
    outputPath: 'images/'
  }
}

Asset Module Options

Automatic Choice (asset)

Replaces url-loader with limit:
{
  test: /\.png$/,
  type: 'asset',
  parser: {
    dataUrlCondition: {
      maxSize: 8 * 1024 // 8kb
    }
  }
}

Always Inline (asset/inline)

Replaces url-loader with no limit:
{
  test: /\.svg$/,
  type: 'asset/inline'
}

Custom Data URL Generator

{
  test: /\.svg$/,
  type: 'asset/inline',
  generator: {
    dataUrl: content => {
      return svgToMiniDataURI(content.toString());
    }
  }
}

Performance Considerations

Benefits of Inlining

  • Reduces HTTP requests
  • Eliminates separate file loading
  • Useful for small assets

Drawbacks of Inlining

  • Increases bundle size
  • Cannot be cached separately
  • Larger bundle = slower initial load
  • Base64 encoding adds ~33% size overhead

Best Practices

Only inline very small files (< 10kb). Larger files should be loaded separately for better caching.
// Good: Small icons and fonts
{
  test: /\.(woff2|svg)$/,
  type: 'asset',
  parser: {
    dataUrlCondition: {
      maxSize: 8 * 1024
    }
  }
}

// Bad: Large images
{
  test: /\.(jpg|png)$/,
  type: 'asset/inline' // Bloats bundle!
}

Complete Migration Example

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        loader: 'url-loader',
        options: {
          limit: 8192,
          name: '[name].[contenthash:8].[ext]',
          outputPath: 'images/'
        }
      },
      {
        test: /\.svg$/i,
        loader: 'url-loader',
        options: {
          limit: 10000,
          mimetype: 'image/svg+xml'
        }
      }
    ]
  }
};

Common Issues

Issue: Bundle Size Too Large

Cause: Too many or too large files inlined. Solution: Reduce maxSize limit:
parser: {
  dataUrlCondition: {
    maxSize: 4 * 1024 // Reduce from 8kb to 4kb
  }
}

Issue: File Not Inlined

Cause: File exceeds size limit. Solution: Increase limit or use asset/inline:
type: 'asset/inline' // Always inline

Issue: Wrong MIME Type

Solution: Specify correct MIME type:
generator: {
  dataUrl: {
    mimetype: 'image/svg+xml'
  }
}

Key Differences

Featureurl-loaderAsset Modules
InstallationRequiredBuilt-in
Size limitlimit optionmaxSize in bytes
Always inlinelimit: Infinitytype: 'asset/inline'
Fallbackfile-loaderasset/resource
Configurationoptionsparser + generator

Resources