express-negotiator

raw JSON →
1.1.0 verified Sat Apr 25 auth: no javascript

An Express/Connect middleware for content negotiation of static files, inspired by Apache mod_negotiation. Version 1.1.0 has no recent updates. It rewrites req.url based on exact matches, locale GET parameter, cookie, and Accept-Language/Accept headers, in priority order. Differentiates from other negotiation libraries by integrating directly with express.static and handling ETags for conditional requests. Requires cookieParser when using cookie-based locale.

error Error: Most middleware (like cookieParser) is no longer bundled with Express and must be installed separately.
cause Express 4+ removed bundled middleware; cookieParser is now in the cookie-parser package.
fix
Run 'npm install cookie-parser' and use 'import cookieParser from 'cookie-parser'' instead of 'express.cookieParser()'.
error TypeError: negotiator is not a function
cause Named import instead of default import in ESM.
fix
Use 'import negotiator from 'express-negotiator'' instead of 'import { negotiator } from 'express-negotiator''.
error Cannot find module 'express-negotiator'
cause Package not installed.
fix
Run 'npm install express-negotiator' in your project directory.
gotcha Negotiator rewrites req.url to a negotiated filename, which may affect downstream middleware that inspects req.url.
fix Run negotiator right before express.static and after any middleware that depends on the original url.
deprecated The package uses express.cookieParser() which is deprecated in Express 4+; use cookie-parser middleware instead.
fix Install and use cookie-parser as a separate middleware.
gotcha When no acceptable file is found, req.url is left untouched, which may cause the static middleware to serve a non-negotiated file or 404.
fix Ensure that your static root contains all negotiated variants or handle the case when no match is found.
gotcha The ETag format includes Content-Type and locale, but if you use a CDN or proxy that calculates its own ETag, conditional requests may not work as expected.
fix Disable custom ETag generation in the CDN/proxy or ensure it passes the ETag from the origin.
gotcha If the request URL already exactly matches a file, negotiator does not rewrite, ignoring the negotiation parameters.
fix Design your URL scheme to avoid exact matches when negotiation is desired, e.g., use a path without extension.
npm install express-negotiator
yarn add express-negotiator
pnpm add express-negotiator

Sets up express with negotiator middleware before static file serving, using a locale cookie for negotiation.

import express from 'express';
import negotiator from 'express-negotiator';
import cookieParser from 'cookie-parser';

const root = '/path/to/static/files';
const app = express();

app.use(cookieParser());
app.use(negotiator({ root: root, cookieName: 'locale' }));
app.use(express.static(root));

app.listen(1337, () => {
  console.log('Server listening on port 1337');
});