DNS Prefetch Control Middleware for Express
The `dns-prefetch-control` package provides an Express.js middleware to manage the `X-DNS-Prefetch-Control` HTTP response header. This header influences whether browsers perform DNS prefetching, an optimization where browsers proactively resolve domain names for links and resources that a user might access, potentially reducing perceived latency. The current stable version of this standalone package is 0.3.0, last published seven years ago. While simple and focused, its primary differentiator was its integration into the broader Helmet.js security suite. Modern usage of this functionality is typically through the `helmet` package itself (e.g., `helmet({ xDnsPrefetchControl: { allow: true } })`), as the standalone `dns-prefetch-control` repository has been archived, indicating it's no longer actively maintained as a separate entity. Disabling DNS prefetching, which is the default for security-focused middleware like Helmet.js, enhances user privacy by preventing speculative DNS lookups that could reveal browsing patterns, albeit at a potential slight performance cost.
Common errors
-
TypeError: dnsPrefetchControl is not a function
cause This usually occurs when attempting to use an ESM `import` statement for a CommonJS module that exports a function directly (e.g., `module.exports = function`) without correctly accessing its default property, or if using a named import for a default export.fixEnsure correct import syntax: `import dnsPrefetchControl from 'dns-prefetch-control';` for ESM, or `const dnsPrefetchControl = require('dns-prefetch-control');` for CommonJS. If using TypeScript and `esModuleInterop` is `false`, you might need `import * as dnsPrefetchControl from 'dns-prefetch-control';`. -
X-DNS-Prefetch-Control header is not being set or has an unexpected value
cause The middleware might not be applied correctly to the Express application, or other middleware might be overwriting the header. Also, if using the standalone package alongside `helmet`, `helmet` might take precedence.fixVerify `app.use(dnsPrefetchControl(...))` is placed early in your middleware chain. If using `helmet`, ensure `xDnsPrefetchControl` is configured within the `helmet` options object and avoid redundant standalone `dns-prefetch-control` usage. Use browser developer tools to inspect response headers.
Warnings
- deprecated The standalone `dns-prefetch-control` package is effectively abandoned, with its GitHub repository archived. Its functionality has been integrated directly into the `helmet` package. Users should migrate to using `helmet` directly for this feature.
- gotcha Enabling DNS prefetching (`allow: true`) can improve page load performance by proactively resolving domain names. However, it can also have privacy implications, as it causes browsers to make DNS requests for links a user might not actually click, potentially revealing browsing interests to DNS servers and network observers.
- gotcha The `X-DNS-Prefetch-Control` header is a non-standard header, though widely supported by modern browsers. Its behavior might vary slightly across different browser implementations.
- gotcha Overusing DNS prefetch hints (e.g., via `<link rel="dns-prefetch" ...>` or excessively broad prefetching) can paradoxically degrade performance by overwhelming the browser's internal queue or causing unnecessary lookups, especially for domains that are not actually used.
Install
-
npm install dns-prefetch-control -
yarn add dns-prefetch-control -
pnpm add dns-prefetch-control
Imports
- dnsPrefetchControl
const dnsPrefetchControl = require('dns-prefetch-control'); // Correct for CJS, but prefer ESM where possible. // import { dnsPrefetchControl } from 'dns-prefetch-control'; // Incorrect named import for CJS default export.import dnsPrefetchControl from 'dns-prefetch-control';
- DnsPrefetchControlOptions
import { DnsPrefetchControlOptions } from 'dns-prefetch-control'; - dnsPrefetchControl (from Helmet)
import { dnsPrefetchControl } from 'helmet';import helmet from 'helmet'; // ... app.use(helmet({ xDnsPrefetchControl: { allow: true } }));
Quickstart
import express from 'express';
import dnsPrefetchControl from 'dns-prefetch-control';
// For modern usage, consider importing helmet directly:
// import helmet from 'helmet';
const app = express();
const PORT = process.env.PORT || 3000;
// Use dns-prefetch-control to disable DNS prefetching (default and recommended for privacy)
app.use(dnsPrefetchControl());
// Example of explicitly allowing DNS prefetching (potential privacy trade-off, slight performance gain)
// app.use(dnsPrefetchControl({ allow: true }));
// If using Helmet.js, you would configure it like this (and omit the standalone middleware):
// app.use(helmet({
// xDnsPrefetchControl: { allow: false } // or true
// }));
app.get('/', (req, res) => {
res.send('<h1>DNS Prefetch Control Example</h1><p>Check your network headers for X-DNS-Prefetch-Control.</p>');
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('X-DNS-Prefetch-Control header should be set.');
});