AddonPulse
Proxy Guide

Express.js Proxy Setup

Configure Express.js middleware to proxy AddonPulse tracking requests

Express.js makes it easy to proxy AddonPulse tracking using middleware. This guide shows how to set up a reverse proxy using http-proxy-middleware.

Overview

The http-proxy-middleware package provides a simple way to proxy requests in Express applications, making it perfect for routing analytics requests to AddonPulse servers.

What you'll achieve:

  • Proxy all AddonPulse endpoints through your Express app
  • Forward necessary headers for accurate tracking
  • Optional caching for better performance
  • Support all AddonPulse features

Prerequisites

  • Node.js and Express.js application
  • npm or yarn package manager
  • Your AddonPulse instance URL https://app.addonpulse.com
  • Your AddonPulse site ID

Implementation

Install http-proxy-middleware

Install the proxy middleware package:

npm install http-proxy-middleware

Or with yarn:

yarn add http-proxy-middleware

Configure Environment Variables

Create or update your .env file:

# .env
ADDONPULSE_HOST=https://app.addonpulse.com

Install dotenv if not already: npm install dotenv

Add Proxy Middleware to Express

Minimal setup with basic tracking:

// server.js
require('dotenv').config();
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();
const ADDONPULSE_HOST = process.env.ADDONPULSE_HOST || 'https://app.addonpulse.com';

// Proxy script and track endpoints only
app.use(['/analytics/script.js', '/analytics/track'], createProxyMiddleware({
  target: ADDONPULSE_HOST,
  changeOrigin: true,
  pathRewrite: {
    '^/analytics': '/api',
  },
  onProxyReq: (proxyReq, req, res) => {
    const clientIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
    proxyReq.setHeader('X-Forwarded-For', clientIp);
    proxyReq.setHeader('X-Real-IP', clientIp);
  },
}));

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

For TypeScript projects:

// server.ts
import 'dotenv/config';
import express, { Request, Response } from 'express';
import { createProxyMiddleware, Options } from 'http-proxy-middleware';

const app = express();
const ADDONPULSE_HOST = process.env.ADDONPULSE_HOST || 'https://app.addonpulse.com';

const proxyOptions: Options = {
  target: ADDONPULSE_HOST,
  changeOrigin: true,
  pathRewrite: {
    '^/analytics': '/api',
  },
  onProxyReq: (proxyReq, req, res) => {
    const clientIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
    proxyReq.setHeader('X-Forwarded-For', clientIp as string);
    proxyReq.setHeader('X-Real-IP', clientIp as string);
  },
  logLevel: 'warn',
};

app.use('/analytics', createProxyMiddleware(proxyOptions));

app.use('/analytics/site/tracking-config', createProxyMiddleware({
  target: ADDONPULSE_HOST,
  changeOrigin: true,
  pathRewrite: {
    '^/analytics/site': '/api/site',
  },
  onProxyReq: proxyOptions.onProxyReq,
}));

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Update Your Tracking Script

In your HTML or template files:

<script src="/analytics/script.js" async data-site-id="YOUR_SITE_ID"></script>

Start Your Server

node server.js

Or with nodemon for development:

npm install -D nodemon
npx nodemon server.js

Verify the Setup

  1. Test script endpoint:

    curl -I http://localhost:3000/analytics/script.js
  2. Open your app in a browser with Developer Tools

  3. Check Network tab: Requests should go to /analytics/*

  4. Verify in AddonPulse dashboard: Data should appear

How It Works

The http-proxy-middleware intercepts requests matching the specified paths and forwards them to AddonPulse:

  1. Request to /analytics/script.js is intercepted
  2. Path is rewritten to /api/script.js
  3. Request is forwarded to https://app.addonpulse.com/api/script.js
  4. Client IP headers are added for accurate tracking
  5. Response is sent back to the browser

Advanced Configuration

Caching Responses

Add caching for better performance:

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 3600 }); // 1 hour default

// Install: npm install node-cache

// Caching middleware for scripts
const cacheMiddleware = (req, res, next) => {
  const key = req.originalUrl;
  const cachedResponse = cache.get(key);

  if (cachedResponse) {
    res.set('X-Cache-Status', 'HIT');
    return res.send(cachedResponse);
  }

  // Store original send
  const originalSend = res.send.bind(res);
  res.send = (body) => {
    cache.set(key, body);
    res.set('X-Cache-Status', 'MISS');
    return originalSend(body);
  };
  next();
};

// Apply caching only to script files
app.use('/analytics/script.js', cacheMiddleware);
app.use('/analytics/script.js', createProxyMiddleware({
  // ... proxy config
}));

Rate Limiting

Protect your proxy with rate limiting:

const rateLimit = require('express-rate-limit');

// Install: npm install express-rate-limit

const analyticsLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 100, // Limit each IP to 100 requests per minute
  message: 'Too many requests from this IP',
  standardHeaders: true,
  legacyHeaders: false,
});

// Apply to tracking endpoints
app.use('/analytics/track', analyticsLimiter);
app.use('/analytics/track', createProxyMiddleware({
  // ... proxy config
}));

Error Handling

Add error handling for proxy failures:

app.use('/analytics', createProxyMiddleware({
  target: ADDONPULSE_HOST,
  changeOrigin: true,
  pathRewrite: {
    '^/analytics': '/api',
  },
  onError: (err, req, res) => {
    console.error('Proxy error:', err);
    res.status(500).json({ error: 'Analytics proxy error' });
  },
  onProxyReq: (proxyReq, req, res) => {
    const clientIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
    proxyReq.setHeader('X-Forwarded-For', clientIp);
    proxyReq.setHeader('X-Real-IP', clientIp);
  },
}));

CORS Configuration

If serving API endpoints to other domains:

const cors = require('cors');

// Install: npm install cors

app.use('/analytics', cors({
  origin: ['https://yourdomain.com', 'https://www.yourdomain.com'],
  credentials: true,
}));

app.use('/analytics', createProxyMiddleware({
  // ... proxy config
}));

Troubleshooting

Requests timing out

Problem: Proxy requests hang or timeout.

Solution: Increase timeout limits:

app.use('/analytics', createProxyMiddleware({
  target: ADDONPULSE_HOST,
  changeOrigin: true,
  timeout: 30000, // 30 seconds
  proxyTimeout: 30000,
  pathRewrite: {
    '^/analytics': '/api',
  },
}));

Incorrect geolocation

Problem: All visitors show server's location.

Solution: Ensure IP forwarding is configured:

onProxyReq: (proxyReq, req, res) => {
  const clientIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
  proxyReq.setHeader('X-Forwarded-For', clientIp);
  proxyReq.setHeader('X-Real-IP', clientIp);
}

Path rewriting issues

Problem: 404 errors on AddonPulse endpoints.

Solution: Check path rewriting is correct:

pathRewrite: {
  '^/analytics': '/api', // /analytics/script.js → /api/script.js
}

Debug by logging:

onProxyReq: (proxyReq, req, res) => {
  console.log('Proxying:', req.method, req.path, '→', proxyReq.path);
}

On this page