Connect Pushstate Middleware
raw JSON →connect-pushstate is a Connect middleware designed to facilitate client-side routing in single-page applications (SPAs) by rewriting non-asset requests to the application's root. Released as version 1.1.0, this package appears to be abandoned, with its last update occurring approximately nine years ago. It operates by identifying requests that lack a file extension (presumed to be application routes) and internally redirects them to the root path, while preserving the original URL for the client-side router to process. Requests with file extensions (e.g., for images, stylesheets, JavaScript files) are left untouched. The middleware offers optional `root`, `allow`, and `disallow` regular expression configurations to provide finer control over which paths are affected, making it suitable for scenarios where an API or specific server-rendered pages coexist with an SPA. Its key differentiator lies in its simple, focused approach within the `connect` ecosystem, providing a lightweight solution for pushstate routing without the overhead of full-fledged server-side frameworks.
Common errors
error Error [ERR_REQUIRE_ESM]: require() of ES Module ... ↓
const pushState = require('connect-pushstate'); as connect-pushstate is a CommonJS module. error TypeError: app.use is not a function ↓
app is an instance created by connect() or express(). For example, const app = connect();. error Cannot GET /some-client-route (or similar 404/file not found) after refresh ↓
serve-static) is correctly configured to serve your application's index.html for the root path, and that index.html exists in the specified static directory and is reachable. error ReferenceError: pushState is not defined ↓
const pushState = require('connect-pushstate'); at the top of your file to properly import the middleware. Warnings
deprecated The `connect-pushstate` package has been abandoned for approximately nine years and receives no further updates or security patches. Using it in production introduces potential security vulnerabilities and compatibility issues with modern JavaScript runtimes and dependencies. ↓
breaking The package is deeply tied to the `connect` ecosystem, which has largely been superseded by Express and other modern frameworks. Direct integration with newer Node.js versions or different server setups may require significant workarounds. ↓
gotcha This package is a CommonJS module and does not provide ES module exports. Attempting to `import` it will result in an `ERR_REQUIRE_ESM` error in pure ESM environments. ↓
gotcha The default behavior rewrites requests without a file extension. This heuristic can be problematic for URLs like `/api.json/data` or `/download.pdf?inline=true` which are intended for direct server processing but might lack a path segment with a 'real' file extension, leading to unintended rewrites. ↓
Install
npm install connect-pushstate yarn add connect-pushstate pnpm add connect-pushstate Imports
- pushState wrong
import pushState from 'connect-pushstate';correctconst pushState = require('connect-pushstate'); - pushState() wrong
app.use(require('connect-pushstate')({ root: '/app' }));correctapp.use(pushState({ root: '/app' })); - Options wrong
pushState('/api')correctpushState({ allow: '^/api', disallow: '^/admin' })
Quickstart
const connect = require('connect');
const morgan = require('morgan');
const serveStatic = require('serve-static');
const pushState = require('connect-pushstate');
const port = process.env.PORT ?? 3000;
// Create a 'www' directory and place an index.html inside for this example.
// For example, www/index.html could contain: <h1>Hello SPA!</h1><script>history.pushState({}, '', '/home')</script>
const app = connect()
.use(pushState())
.use(serveStatic('www/')) // Serve your static client-side application files from the 'www' directory
.use(morgan('dev'))
.listen(port, function() {
console.log('Application server stated on port', port);
});
// To run:
// 1. Create a directory named 'www'.
// 2. Inside 'www', create an 'index.html' file.
// 3. Run 'node your-server-file.js'
// 4. Navigate to http://localhost:3000/some-client-route (it should serve index.html)