Connect LiveReload Middleware
connect-livereload is a Connect/Express middleware designed to inject the LiveReload script directly into HTML responses. This eliminates the need for a browser extension, simplifying the development workflow by automatically reloading the browser upon file changes detected by companion tools like `grunt-contrib-watch`. The current stable version is 0.6.1, which was published approximately 7 years ago (December 2018), indicating that the package is largely unmaintained. Its primary differentiation is the server-side injection, which contrasts with client-side browser extensions. It does not, however, serve the `livereload.js` script itself, requiring another module (e.g., a LiveReload server like `node-livereload`) to provide it. Configuration options allow for specifying the LiveReload server port, ignoring certain file types (e.g., `.js`, `.css`), or customizing the HTML detection and injection rules.
Common errors
-
GET http://localhost:35729/livereload.js net::ERR_CONNECTION_REFUSED
cause The `livereload.js` script requested by the browser could not be fetched. This almost always means that the separate LiveReload server (which is responsible for serving this script) is not running or is not listening on the expected port.fixStart your LiveReload server (e.g., `livereload.createServer().watch(...)`) and ensure it's configured to listen on port 35729 (or the port specified in `connect-livereload` options). Verify no other process is blocking this port. -
LiveReload not working / Browser not reloading on file changes.
cause This is a general issue with multiple potential causes: a conflicting browser extension, incorrect middleware placement, `connect-livereload` not configured for the correct file types (via `ignore` or `include` options), or the LiveReload server not watching the correct directories.fix1. Disable browser LiveReload extensions. 2. Verify `connect-livereload` is placed correctly in the middleware stack (before static for HTML). 3. Check `ignore` and `include` options to ensure desired files are not excluded. 4. Ensure your LiveReload server (`livereload` package or similar) is actively watching the correct directories and communicating with the browser. -
TypeError: Cannot read properties of undefined (reading 'split')
cause This error can occur if `connect-livereload` tries to process a response that is not a string (e.g., a buffer, or a response from middleware that doesn't `res.write` or `res.end` with a string), particularly within its `html` detection function.fixEnsure `connect-livereload` is only processing text-based HTML responses. Review your middleware stack and `ignore` rules. If you have custom middleware modifying `res.write`/`res.end`, ensure compatibility. You can also customize the `html` option to better suit your content detection if non-standard responses are being processed.
Warnings
- deprecated The `connect-livereload` package is effectively abandoned, with the last release (v0.6.1) dating back to December 2018. While it may still function for basic use cases, it is no longer actively maintained, meaning no new features, bug fixes, or security updates are to be expected. Consider alternative, actively maintained solutions for live reloading in modern development workflows.
- gotcha This middleware only injects the client-side LiveReload script. It does NOT serve the `livereload.js` file itself or provide the actual file watching and reload triggering mechanism. You *must* run a separate LiveReload server (e.g., `livereload` npm package, `grunt-contrib-watch`, `webpack-dev-server`) that listens on the specified port (default 35729) and serves the `livereload.js` client script.
- gotcha If you have a browser-based LiveReload extension installed, it can conflict with `connect-livereload`'s server-side injection, leading to unexpected behavior or reloads not functioning correctly.
- gotcha The placement of `connect-livereload` middleware in your Express/Connect application's middleware stack is crucial. If you need it to inject into static HTML files, it must be placed *before* `express.static()` or similar static file serving middleware. If only for dynamic content, it can be placed after static routes but before specific dynamic route handlers.
Install
-
npm install connect-livereload -
yarn add connect-livereload -
pnpm add connect-livereload
Imports
- connect-livereload
import livereloadMiddleware from 'connect-livereload';
const livereloadMiddleware = require('connect-livereload'); - middleware factory function
app.use(connect_livereload);
app.use(require('connect-livereload')({ port: 35729 })); - TypeScript types
import { Request, Response, NextFunction } from 'connect-livereload';import * as livereload from 'connect-livereload'; // Or for the factory function signature: import connectLivereload = require('connect-livereload');
Quickstart
const express = require('express');
const path = require('path');
const livereload = require('livereload');
const connectLiveReload = require('connect-livereload');
// Initialize a LiveReload server
const lrserver = livereload.createServer();
lrserver.watch(path.join(__dirname, 'public'));
const app = express();
const port = 3000;
// Use connect-livereload middleware *before* static routes to inject into HTML
// For dynamic content, place it after static routes but before actual dynamic route handlers.
app.use(connectLiveReload({
port: 35729,
// Ignore common non-HTML files by default
ignore: [/.js(\?.*)?$/, /.css(\?.*)?$/, /.svg(\?.*)?$/, /.ico(\?.*)?$/, /.woff(\?.*)?$/, /.png(\?.*)?$/, /.jpg(\?.*)?$/, /.jpeg(\?.*)?$/, /.gif(\?.*)?$/, /.pdf(\?.*)?$/]
}));
// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
// Example route for dynamic content (which will also be reloaded)
app.get('/dynamic', (req, res) => {
res.send(`<!DOCTYPE html>
<html lang="en">
<head><title>Dynamic Page</title></head>
<body>
<h1>Welcome to the dynamic page!</h1>
<p>Current time: ${new Date().toLocaleTimeString()}</p>
</body>
</html>`);
});
app.listen(port, () => {
console.log(`Express app listening at http://localhost:${port}`);
console.log(`LiveReload server running on port 35729, watching ${path.join(__dirname, 'public')}`);
});
// Create a 'public' directory and an 'index.html' inside for testing:
// echo '<!-- index.html -->\n<!DOCTYPE html>\n<html lang="en">\n<head><title>Home</title></head>\n<body>\n <h1>Hello World!</h1>\n <p>Edit this file to see live reload.</p>\n</body>\n</html>' > public/index.html