Connect Pushstate Middleware

raw JSON →
1.1.0 verified Thu Apr 23 auth: no javascript abandoned

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.

error Error [ERR_REQUIRE_ESM]: require() of ES Module ...
cause Attempting to use ES module `import` syntax with `connect-pushstate`, which is a CommonJS module.
fix
Use const pushState = require('connect-pushstate'); as connect-pushstate is a CommonJS module.
error TypeError: app.use is not a function
cause `connect-pushstate` is designed for the `connect` (or `express`) middleware signature. This error occurs if `app` is not a `connect` or `express` application instance.
fix
Ensure 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
cause The server is not configured to serve the `index.html` for rewritten routes. This often means the static file serving middleware (e.g., `serve-static`) is missing, misconfigured (e.g., wrong root directory), or the `index.html` file itself is missing from the served directory.
fix
Ensure your static file serving middleware (e.g., 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
cause The `require('connect-pushstate')` call was omitted or incorrectly assigned to a variable with a different name.
fix
Add const pushState = require('connect-pushstate'); at the top of your file to properly import the middleware.
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.
fix Migrate to a currently maintained alternative. For Express-based applications, a simple wildcard route to serve `index.html` is common. For other frameworks, look for dedicated SPA routing middleware.
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.
fix Consider using more modern routing solutions available in frameworks like Express (e.g., `res.sendFile('index.html')` with a wildcard route) or integrated client-side routers.
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.
fix If in a pure ESM project, you may need to use dynamic `import()` or wrapper functions, but it's generally recommended to stick to `require()` for this package. A more modern alternative might be preferred.
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.
fix Leverage the `allow` and `disallow` options with precise regular expressions to explicitly control which paths are affected, especially for API endpoints or specific server-side routes.
npm install connect-pushstate
yarn add connect-pushstate
pnpm add connect-pushstate

Demonstrates how to integrate `connect-pushstate` with `connect` and `serve-static` to serve a single-page application, routing all non-asset requests to the root index.html for client-side routing.

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)