npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

base-href-runtime-webpack-plugin

v1.1.0

Published

[![npm version](https://badge.fury.io/js/base-href-runtime-webpack-plugin.svg)](https://badge.fury.io/js/base-href-runtime-webpack-plugin)

Readme

base-href-runtime-webpack-plugin

npm version

Extension for html-webpack-plugin to programmatically insert or update <base href="..."> tag in runtime depending on window.location.pathname.

It inserts inline <script> in your index.html output which generates (rewrites) <base href="...">

Why

When your application is proxied with many different domains and prefixes you might need to detect publicPath so you could resolve requests for assets correctly.

Example

Your application is hosted on example.com and you have 2 known entrypoints (proxies) for this application:

app.test.com/ui/app -> example.com
app2.io/ui/test/entrypoint -> example.com

So you want to open app.test.com/ui/app and resolve index.js request to app.test.com/ui/app/index.js (-> example.com/index.js)

For this purpose you want to generate different <base> tag:

<!-- for app.test.com/ui/app/ (/ui/app/) -->
<base href="/ui/app/">
<script src="index.js" /> <!-- /ui/app/index.js -->

<!-- for app2.io/ui/test/entrypoint (/ui/test/entrypoint/) -->
<base href="/ui/test/entrypoint/">
<script src="index.js" /> <!-- /ui/test/entrypoint/index.js -->

Thus <base> tag for the same index.html has to be generated in runtime.

Installation

For webpack v5 use latest (^1.1.0):
npm i --save-dev base-href-runtime-webpack-plugin

Usage

Prepare HtmlWebpackPlugin, it should generate relative paths for assets.

new HtmlWebpackPlugin({
  template: 'public/index.html',
  filename: 'index.html',
  // ...,
- publicPath: '/',
+ publicPath: 'auto', // assets paths must be relative
+ base: '/' // same as fallbackBaseHref, see https://github.com/jantimon/html-webpack-plugin#base-tag
}),

Init base-href-runtime-webpack-plugin:

const BaseHrefRuntimeWebpackPlugin = require('base-href-runtime-webpack-plugin');

plugins: [
  // ...,
  new BaseHrefRuntimeWebpackPlugin({
    fallbackBaseHref: '/', // in case when we didn't match location.pathname 
    publicPaths: [ // availabled prefixes. Order is important!
      '/ui/app/', // <base href="/ui/app/">
      '/ui/test/entrypoint/', // <base href="/ui/test/entrypoint/">
      '/a/b/c/d/e/', // <base href="/a/b/c/d/e/">
    ],
  }),
]

It will inject <script></script> in your index.html. This script compares current window.location.pathname and provided publicPaths. Then it updates <base href="..."> if we have a match. Otherwise it sets fallbackBaseHref value in your <base href="...">

Plugin leaves your template untouched if fallbackBaseHref and publicPaths options are not provided.

Setup application router (optional)

You might want to use publicPaths to prepare your application router (react-router, vue-router, etc.)

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { publicPaths, fallbackBaseHref } from './lib/constants/config'; // use same variable as publicPaths in you webpack.config.js

const App = ({ basename }) => {
  <Router basename={basename}>
    {/* ... your app content ... */}
  </Router>
}

const getBasename = (pathname) => {
  const publicPath = publicPaths.find(publicPath => pathname.includes(publicPath.replace(/\/$/, '')));
  return publicPath || fallbackBaseHref;
}

ReactDOM.render(<App basename={getBasename(window.location.pathname)} />, document.getElementById('#app'));

Caveats

https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work#preload_scanner

The preload scanner will parse through the content available and request high priority resources like CSS, JavaScript, and web fonts. <...> It will retrieve resources in the background so that by the time the main HTML parser reaches requested assets, they may possibly already be in flight, or have been downloaded.

It means that a browser requests all page's resources before you execute any <script>. So if your <base href="..."> tag is being changed by the <script> then your browser will repeat these requests again.

Example:

<html>
<head>
  <base href="/unknown/">
  <script type="text/javascript">
    console.log('Initial document.baseURI:', document.baseURI);
    document.querySelector('base').href = '/'
    console.log('New document.baseURI:', document.baseURI);
  </script>
  <script src="js/index.js"></script>

  <!-- @NOTE: I don't know why, but Chrome won't request script below again even after baseURI change -->
  <!-- <script src="js/index.js" />-->
  <!-- So <script src="..." /> and <script src="..."></script> have different behaviour (WTF?!) -->
</head>
</html>

Chrome's Network tab result (js/index.js request duplicated):

Supported browsers

All modern browsers, even IE7

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base#browser_compatibility

References

https://www.npmjs.com/package/base-href-webpack-plugin

https://github.com/jantimon/html-webpack-plugin#base-tag

Contribution

Feel free to contribute to this project by submitting issues and/or pull requests.

License

MIT