Express.js Proxy

Set up an EngageTrack proxy with Express.js middleware.

Express.js Proxy

Use http-proxy-middleware to proxy EngageTrack requests through your Express.js server.

Install Dependencies

npm install http-proxy-middleware

Route Configuration

const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");
 
const app = express();
 
// Proxy the SDK script
app.use(
	"/js/script.js",
	createProxyMiddleware({
		target: "https://cdn.engagetrack.net",
		changeOrigin: true,
		pathRewrite: { "^/js/script.js": "/sdk.js" },
	})
);
 
// Proxy the event API endpoint
app.use(
	"/api/event",
	createProxyMiddleware({
		target: "https://api.engagetrack.net",
		changeOrigin: true,
		pathRewrite: { "^/api/event": "/api/v1/event" },
		onProxyReq: (proxyReq, req) => {
			// Forward the real client IP for geolocation
			const clientIp =
				req.headers["x-forwarded-for"] ||
				req.socket.remoteAddress;
			if (clientIp) {
				proxyReq.setHeader("X-Forwarded-For", clientIp);
			}
		},
	})
);
 
// ... your other routes ...
 
app.listen(3000, () => {
	console.log("Server running on port 3000");
});

TypeScript Version

import express from "express";
import { createProxyMiddleware } from "http-proxy-middleware";
 
const app = express();
 
app.use(
	"/js/script.js",
	createProxyMiddleware({
		target: "https://cdn.engagetrack.net",
		changeOrigin: true,
		pathRewrite: { "^/js/script.js": "/sdk.js" },
	})
);
 
app.use(
	"/api/event",
	createProxyMiddleware({
		target: "https://api.engagetrack.net",
		changeOrigin: true,
		pathRewrite: { "^/api/event": "/api/v1/event" },
		onProxyReq: (proxyReq, req) => {
			const clientIp =
				req.headers["x-forwarded-for"] ||
				req.socket.remoteAddress;
			if (clientIp) {
				proxyReq.setHeader("X-Forwarded-For", String(clientIp));
			}
		},
	})
);
 
app.listen(3000);

The changeOrigin: true option sets the Host header to the target hostname, which is required for the upstream server to route the request correctly.

Without http-proxy-middleware

If you prefer not to add a dependency, use Node's built-in fetch (Node 18+):

const express = require("express");
 
const app = express();
app.use(express.raw({ type: "application/json", limit: "1mb" }));
 
// Proxy the SDK script
app.get("/js/script.js", async (req, res) => {
	const response = await fetch("https://cdn.engagetrack.net/sdk.js");
	res.set("Content-Type", "application/javascript");
	res.set("Cache-Control", "public, max-age=3600");
	const body = await response.text();
	res.send(body);
});
 
// Proxy the event endpoint
app.post("/api/event", async (req, res) => {
	const clientIp = req.headers["x-forwarded-for"] || req.socket.remoteAddress;
 
	const response = await fetch("https://api.engagetrack.net/api/v1/event", {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
			"X-Forwarded-For": clientIp || "",
		},
		body: req.body,
	});
 
	res.status(response.status).send(await response.text());
});
 
app.listen(3000);

Always forward the X-Forwarded-For header with the client's real IP address. Without it, all visitors will be geolocated to your server's location.

Updated Script Tag

<script
	defer
	data-site-id="YOUR_SITE_ID"
	data-api="https://yourdomain.com/api/event"
	src="https://yourdomain.com/js/script.js"
></script>