Skip to main content

Overview

raw-loader imports file contents as strings. This is useful for loading text files, SVG markup, HTML templates, shaders, and other text-based assets as strings in your JavaScript code.
In webpack 5, you can use Asset Modules with type: 'asset/source' as an alternative to raw-loader.

Installation

npm install -D raw-loader

Basic Usage

module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/i,
        use: 'raw-loader'
      }
    ]
  }
};

Common Use Cases

Text Files

{
  test: /\.txt$/,
  use: 'raw-loader'
}
import readme from './README.txt';
document.body.innerHTML = `<pre>${readme}</pre>`;

HTML Templates

{
  test: /\.html$/,
  use: 'raw-loader',
  exclude: /index\.html/
}
import template from './templates/card.html';

const container = document.createElement('div');
container.innerHTML = template;

SVG as String

{
  test: /\.svg$/,
  use: 'raw-loader'
}
import iconSvg from './icons/star.svg';

const div = document.createElement('div');
div.innerHTML = iconSvg;

Shader Files

{
  test: /\.(glsl|vs|fs|vert|frag)$/,
  use: 'raw-loader'
}
import vertexShader from './shaders/vertex.glsl';
import fragmentShader from './shaders/fragment.glsl';

const material = new THREE.ShaderMaterial({
  vertexShader,
  fragmentShader
});

Markdown Files

{
  test: /\.md$/,
  use: 'raw-loader'
}
import markdown from './README.md';
import marked from 'marked';

const html = marked(markdown);
document.body.innerHTML = html;

XML/Configuration Files

{
  test: /\.xml$/,
  use: 'raw-loader'
}
import xmlString from './config.xml';
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

Asset Modules Alternative

Webpack 5 provides a built-in alternative using Asset Modules:
module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: 'raw-loader'
      }
    ]
  }
};
Both approaches work identically. Asset Modules (asset/source) is the modern, built-in approach for webpack 5.

Configuration Examples

Multiple File Types

module.exports = {
  module: {
    rules: [
      {
        test: /\.(txt|md|csv)$/,
        use: 'raw-loader'
      }
    ]
  }
};

With Specific Directory

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        include: path.resolve(__dirname, 'src/templates'),
        use: 'raw-loader'
      }
    ]
  }
};

Excluding Files

module.exports = {
  module: {
    rules: [
      {
        test: /\.html$/,
        exclude: /index\.html$/,
        use: 'raw-loader'
      }
    ]
  }
};

Advanced Patterns

Processing Raw Content

import sqlQuery from './queries/users.sql';

const processedQuery = sqlQuery
  .replace(/\s+/g, ' ')
  .trim();

db.query(processedQuery);

Template System

import template from './template.html';

function render(data) {
  return template.replace(/{{(\w+)}}/g, (match, key) => {
    return data[key] || '';
  });
}

const html = render({
  title: 'Hello',
  content: 'World'
});

Loading Shaders for WebGL

{
  test: /\.(glsl|vs|fs)$/,
  use: 'raw-loader'
}
import vertShader from './shader.vs';
import fragShader from './shader.fs';

const program = gl.createProgram();

const vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, vertShader);
gl.compileShader(vs);

const fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, fragShader);
gl.compileShader(fs);

gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);

TypeScript Support

Add type declarations for raw file imports:
typings.d.ts
declare module '*.txt' {
  const content: string;
  export default content;
}

declare module '*.md' {
  const content: string;
  export default content;
}

declare module '*.html' {
  const content: string;
  export default content;
}

declare module '*.glsl' {
  const content: string;
  export default content;
}
import readme from './README.md'; // TypeScript knows this is a string
console.log(readme.toUpperCase());

Migration to Asset Modules

For webpack 5 projects, consider migrating to Asset Modules:
module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: 'raw-loader'
      },
      {
        test: /\.md$/,
        use: 'raw-loader'
      },
      {
        test: /\.glsl$/,
        use: 'raw-loader'
      }
    ]
  }
};

Common Issues

Issue: Binary Files Not Loading Correctly

Cause: raw-loader is for text files only. Solution: Use file-loader or asset/resource for binary files:
// Text files - use raw-loader
{
  test: /\.txt$/,
  use: 'raw-loader'
}

// Binary files - use asset/resource
{
  test: /\.(png|jpg)$/,
  type: 'asset/resource'
}

Issue: HTML Not Rendering

Solution: Ensure you’re setting innerHTML:
import template from './template.html';

// Correct
element.innerHTML = template;

// Wrong - won't render HTML
element.textContent = template;

Issue: Special Characters Not Encoded

Solution: Process the string as needed:
import content from './file.txt';

const encoded = content
  .replace(/&/g, '&amp;')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;');

Performance Considerations

Loading large text files as strings increases bundle size. Consider:
  • Code splitting for large files
  • Dynamic imports for rarely-used content
  • External file loading for very large datasets
// Dynamic import for large files
const loadLargeText = async () => {
  const { default: content } = await import('./large-file.txt');
  return content;
};

Use Cases Summary

File TypeCommon Use
.txtText content, logs
.htmlTemplates, snippets
.svgInline SVG manipulation
.mdMarkdown processing
.glsl, .vs, .fsWebGL shaders
.sqlSQL queries
.xmlXML parsing
.csvCSV processing

Resources