@rspackjs/plugin-html-tags
v1.0.0
Published
An Rspack plugin to inject extra scripts, links, and meta tags via HtmlRspackPlugin.
Readme
@rspackjs/plugin-html-tags
A self-contained TypeScript rewrite of
html-rspack-tags-plugin
(itself a fork of html-webpack-tags-plugin
by Jon Harris). It keeps the same tag-injection behaviour under its own typed
API, published as a dual ESM/CJS package with a @rspack/core: ^1 || ^2 peer
range, so it installs cleanly alongside Rspack 2 without ERESOLVE errors.
- ✅ Works with Rspack 1.x and 2.x (
@rspack/corepeer^1.0.13 || ^2). - ✅ No dependency on
html-webpack-plugin— hook types come from@rspack/core. - ✅ Strict TypeScript, dual ESM + CJS build, ships
.d.ts. - ✅ Clean, typed options API (
HtmlTagsPluginOptions).
Installation
npm install -D @rspackjs/plugin-html-tags@rspack/core is a peer dependency (you already have it in an Rspack project).
Requires Node >=20.19 (matching @rspack/core).
Usage
HtmlRspackPlugin must come before this plugin in the plugins array.
// rspack.config.mjs
import {rspack} from "@rspack/core";
import HtmlTagsRspackPlugin from "@rspackjs/plugin-html-tags";
export default {
plugins: [
new rspack.HtmlRspackPlugin(),
new HtmlTagsRspackPlugin({
tags: ["a-script.js", "a-style.css"],
append: true,
}),
],
};CommonJS works too — require("@rspackjs/plugin-html-tags") returns the class:
const HtmlTagsRspackPlugin = require("@rspackjs/plugin-html-tags");The named HtmlTagsPluginOptions type is exported for TypeScript consumers:
import type {HtmlTagsPluginOptions} from "@rspackjs/plugin-html-tags";Examples
Scripts, links and metas
new HtmlTagsRspackPlugin({
scripts: [{path: "vendor.js", attributes: {defer: true}}],
links: [{path: "theme.css", attributes: {media: "screen"}}],
metas: [{attributes: {name: "theme-color", content: "#222"}}],
});tags is a convenience list that is split into links/scripts by file
extension (.css → link, .js → script), or by an explicit type: "css" | "js".
Scoping injection to specific HTML files (files)
When multiple HtmlRspackPlugin instances emit different HTML files, restrict a
tag set to specific outputs (matched with minimatch):
new HtmlTagsRspackPlugin({
files: ["index.html"],
tags: ["only-on-index.js"],
});Hash and public path
new HtmlTagsRspackPlugin({
tags: ["app.js"],
hash: true, // append `?<compilation hash>` — also accepts a string or (assetPath, hash) => string
publicPath: "https://cdn.example.com/", // prefix — also accepts true/false or (assetPath, publicPath) => string
});publicPath is applied first, then hash. Both can be overridden per-tag.
Globbing files into tags
new HtmlTagsRspackPlugin({
links: [{path: "assets", globPath: "src/icons", glob: "*.css", globFlatten: false}],
});Copying a source file into the output (sourcePath)
new HtmlTagsRspackPlugin({
links: [{path: "favicon.ico", sourcePath: "src/favicon.ico", attributes: {rel: "icon"}}],
});Externals (scripts only)
Registers the package as a webpack/rspack external and injects its script tag:
new HtmlTagsRspackPlugin({
scripts: [
{
path: "https://unpkg.com/react/umd/react.production.min.js",
external: {packageName: "react", variableName: "React"},
},
],
});Options
All options are optional.
| Option | Type | Default | Description |
| ------------------------------------------------ | --------------------------- | ---------- | ------------------------------------------------------------------------- |
| append | boolean | true | Inject after (true) or before (false) the bundle's own tags. |
| prependExternals | boolean | true | Force external scripts to be prepended (so dependents load after them). |
| tags | string \| object \| Array | — | Mixed tags, split into links/scripts by extension or type. |
| links | string \| object \| Array | — | Link tag(s). |
| scripts | string \| object \| Array | — | Script tag(s) (support external). |
| metas | object \| Array | — | Meta tag(s) (require an attributes object). |
| files | string \| string[] | — | Only inject into HTML outputs matching these minimatch patterns. |
| useHash / addHash / hash | see below | — | Append a hash query to asset paths. |
| usePublicPath / addPublicPath / publicPath | see below | — | Prefix asset paths with a public path. |
| jsExtensions | string \| string[] | [".js"] | Extensions treated as scripts when splitting tags. |
| cssExtensions | string \| string[] | [".css"] | Extensions treated as links when splitting tags. |
Per-tag options (LinkTagOptions / ScriptTagOptions / MetaTagOptions): path,
attributes, glob, globPath, globFlatten, sourcePath, plus the
append/hash/publicPath shortcuts (which override the top-level value), and
external (scripts only).
hash:trueuses the default(assetPath) => assetPath + "?" + hash; astringis used as the hash; a function(assetPath, hash) => stringfully customizes it.useHash/addHashare the explicit boolean/function pair.publicPath:trueuses the compilation public path; astringis used as the prefix; a function(assetPath, publicPath) => stringfully customizes it.usePublicPath/addPublicPathare the explicit pair.
Compatibility
- Rspack:
@rspack/core^1.0.13 || ^2. The plugin tapsHtmlRspackPlugin.getCompilationHooks(compilation)(beforeAssetTagGenerationandalterAssetTagGroups), which exists in both major versions. - Webpack: not supported. This is an Rspack-only plugin; for webpack use the
original
html-webpack-tags-plugin.
Differences from html-rspack-tags-plugin
- Renamed exports: the class is
HtmlTagsRspackPlugin(wasHtmlRspackTagsPlugin) and the options type isHtmlTagsPluginOptions(wasOptions). - Removed the
html-webpack-pluginpeer dependency and thehtmlPluginNameoption /getHooksfallback — this package targetsHtmlRspackPluginonly. - Rewritten in TypeScript; published as dual ESM + CJS with type declarations.
- The "no html plugin" error message now references
HtmlRspackPlugin.
The option fields and runtime behaviour are otherwise unchanged from the original.
Credits
- Original
html-webpack-tags-pluginby Jon Harris. html-rspack-tags-pluginfork by rspack-contrib.
License
MIT — original copyright © 2016 Jon Harris, fork © rspack-contrib, this rewrite © 2026 Anjey Tsibylskij.
