Connect/Express Response Modifier Middleware

raw JSON →
6.0.2 verified Thu Apr 23 auth: no javascript

resp-modifier is a Node.js middleware designed for Connect and Express applications, enabling the modification of HTTP response bodies, particularly HTML. It generalizes the functionality found in packages like `connect-livereload`, focusing solely on response modification rather than live reload specifics. The package allows developers to define multiple replacement rules to transform the outgoing response content, making it suitable for tasks such as injecting scripts, modifying links, or censoring content dynamically. The current stable version is 6.0.2. While the release cadence is not explicitly defined, regular updates suggest active maintenance. Key differentiators include its focused scope on response manipulation and compatibility with standard Connect-style middleware architectures.

error Error: Can't set headers after they are sent.
cause Middleware that attempts to modify headers or send a response after a preceding middleware or route handler has already sent the response.
fix
Review the order of your Express middleware. Ensure resp-modifier is positioned before any route handlers that call res.send() or res.json(), and before other middleware that might finalize the response stream.
error Client receives incomplete or malformed response body.
cause The `Content-Length` header is incorrect after modification, or the modification process itself is corrupting the buffer/stream. This is common if the middleware doesn't correctly update headers or handle different encodings.
fix
Verify that resp-modifier is correctly configured for your content's encoding (e.g., UTF-8). Check if there are any options to manage Content-Length header auto-correction. If modifications are drastic, consider debugging the middleware's internal buffer handling.
gotcha Middleware order is critical. `resp-modifier` must be placed before any middleware that sends the final response or compresses it, to ensure it can intercept and modify the response body. If placed incorrectly, it may not modify content or could cause 'Headers already sent' errors.
fix Ensure `app.use(respModifier(...))` is called early in your middleware chain, before route handlers that `res.send()` or `res.json()`.
gotcha When modifying the response body, especially in a streaming context, incorrect `Content-Length` headers can lead to truncated or incomplete responses from the client's perspective. `resp-modifier` typically buffers the response to perform modifications, which can impact performance for very large responses.
fix Be mindful of performance implications for large response bodies. Consider adding checks within your modification logic to only modify responses of specific content types or sizes if performance is critical.
gotcha Modifying non-HTML content types (like JSON, images, or compressed data) without specific content-type handling can corrupt the response. `resp-modifier` is primarily designed for text-based modifications, particularly HTML.
fix Utilize the middleware's configuration to specify content types to target or include logic to bypass modification for certain `res.getHeader('Content-Type')` values. For example, some libraries allow a `filter` function to control when modification applies.
npm install resp-modifier
yarn add resp-modifier
pnpm add resp-modifier

Demonstrates setting up `resp-modifier` as Express middleware to perform string replacements and inject content into HTML responses.

import express from 'express';
import respModifier from 'resp-modifier';

const app = express();
const PORT = process.env.PORT || 3000;

// Basic usage: replace 'world' with 'developer' in HTML responses
app.use(respModifier({
  rules: [
    {
      match: /world/g,
      replace: 'developer'
    },
    {
      match: /<\/body>/,
      replace: '<script>console.log("Response modified!")</script></body>'
    }
  ]
}));

app.get('/', (req, res) => {
  res.status(200).send('<h1>Hello, world!</h1><p>This is a test page.</p>');
});

app.get('/json', (req, res) => {
  // resp-modifier typically targets HTML responses, 
  // JSON responses might not be affected or could be corrupted if not handled carefully.
  res.json({ message: 'Hello, JSON world!' });
});

app.listen(PORT, () => {
  console.log(`Server listening on http://localhost:${PORT}`);
  console.log('Try visiting / and /json');
});