{"id":18345,"library":"express-negotiator","title":"express-negotiator","description":"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.","status":"active","version":"1.1.0","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","http","content negotiation","connect","accept","accept-language","cookie","express","localization"],"install":[{"cmd":"npm install express-negotiator","lang":"bash","label":"npm"},{"cmd":"yarn add express-negotiator","lang":"bash","label":"yarn"},{"cmd":"pnpm add express-negotiator","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for middleware usage","package":"express","optional":true}],"imports":[{"note":"ESM default import; CJS require is also supported for compatibility.","wrong":"const negotiator = require('express-negotiator')","symbol":"default","correct":"import negotiator from 'express-negotiator'"},{"note":"The module exports a single function; named import will not work.","wrong":"import { negotiator } from 'express-negotiator'","symbol":"negotiator","correct":"import negotiator from 'express-negotiator'"},{"note":"CommonJS require returns the function directly; destructuring will get undefined.","wrong":"const { negotiator } = require('express-negotiator')","symbol":"negotiator","correct":"const negotiator = require('express-negotiator')"}],"quickstart":{"code":"import express from 'express';\nimport negotiator from 'express-negotiator';\nimport cookieParser from 'cookie-parser';\n\nconst root = '/path/to/static/files';\nconst app = express();\n\napp.use(cookieParser());\napp.use(negotiator({ root: root, cookieName: 'locale' }));\napp.use(express.static(root));\n\napp.listen(1337, () => {\n  console.log('Server listening on port 1337');\n});","lang":"javascript","description":"Sets up express with negotiator middleware before static file serving, using a locale cookie for negotiation."},"warnings":[{"fix":"Run negotiator right before express.static and after any middleware that depends on the original url.","message":"Negotiator rewrites req.url to a negotiated filename, which may affect downstream middleware that inspects req.url.","severity":"gotcha","affected_versions":"*"},{"fix":"Install and use cookie-parser as a separate middleware.","message":"The package uses express.cookieParser() which is deprecated in Express 4+; use cookie-parser middleware instead.","severity":"deprecated","affected_versions":"express >=4"},{"fix":"Ensure that your static root contains all negotiated variants or handle the case when no match is found.","message":"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.","severity":"gotcha","affected_versions":"*"},{"fix":"Disable custom ETag generation in the CDN/proxy or ensure it passes the ETag from the origin.","message":"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.","severity":"gotcha","affected_versions":"*"},{"fix":"Design your URL scheme to avoid exact matches when negotiation is desired, e.g., use a path without extension.","message":"If the request URL already exactly matches a file, negotiator does not rewrite, ignoring the negotiation parameters.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Run 'npm install cookie-parser' and use 'import cookieParser from 'cookie-parser'' instead of 'express.cookieParser()'.","cause":"Express 4+ removed bundled middleware; cookieParser is now in the cookie-parser package.","error":"Error: Most middleware (like cookieParser) is no longer bundled with Express and must be installed separately."},{"fix":"Use 'import negotiator from 'express-negotiator'' instead of 'import { negotiator } from 'express-negotiator''.","cause":"Named import instead of default import in ESM.","error":"TypeError: negotiator is not a function"},{"fix":"Run 'npm install express-negotiator' in your project directory.","cause":"Package not installed.","error":"Cannot find module 'express-negotiator'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}