Email tracking is a crucial feature for any email campaign system or bulk mail sender. It helps you understand how many users opened your emails, when, and sometimes even from where. In this article, you’ll learn how to set up your own open tracking system using a tracking pixel and a Node.js + Express backend.
What Is a Tracking Pixel?
A tracking pixel is a 1x1 transparent image that you embed inside an email. When the email is opened by the recipient, their email client loads this image from your server. You can use this request to log an "open event" for that user.
Features We’ll Build
- Embed a tracking pixel in the email HTML
- Handle the image request in Node.js (Express)
- Log the email open event in MongoDB
- Collect metadata like IP, user-agent, timestamp
Technologies Used
- Node.js (Express framework)
- MongoDB (for storing open logs)
- Base64 pixel image
- HTML email template
Setting Up the Backend (Node.js + Express)
Step 1: Initialize a new Node project
mkdir email-tracker
cd email-tracker
npm init -y
npm install express mongoose
Step 2: Create server.js
Here’s the complete code for your tracking server:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const PORT = 3000;
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/emailTracking', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// MongoDB Schema for tracking events
const EmailEvent = mongoose.model('EmailEvent', new mongoose.Schema({
type: String, // 'open'
email: String,
emailId: String,
ip: String,
userAgent: String,
timestamp: { type: Date, default: Date.now }
}));
// Email open tracking route
app.get('/track/open', async (req, res) => {
const { email, emailId } = req.query;
// Extract IP address and user-agent
const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
const userAgent = req.headers['user-agent'];
// Save the open event
await EmailEvent.create({
type: 'open',
email,
emailId,
ip,
userAgent
});
// Send a 1x1 transparent GIF
const pixel = Buffer.from(
'R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==',
'base64'
);
res.set('Content-Type', 'image/gif');
res.end(pixel);
});
// Start server
app.listen(PORT, () => {
console.log(`Tracking server running at http://localhost:${PORT}`);
});
Create the Email Template with Pixel
You now need to add the pixel to the emails you send. Here’s an example email HTML snippet:
<p>Hello John,</p>
<p>We have an exciting offer just for you!</p>
<!-- Tracking Pixel -->
<img
src="https://yourdomain.com/track/open?email=john@example.com&emailId=bulk_campaign_001"
width="1"
height="1"
style="display:none;"
alt=""
/>
Replace
yourdomain.comwith your backend server domain. Use dynamic values foremailId.
Test the Setup
- Run the backend server:
node server.js - Send the test email (you can use tools like Mailtrap, Nodemailer, or Postmark).
- When the email is opened, the pixel will trigger the backend route.
- Open your MongoDB to see entries like
{
"type": "open",
"email": "john@example.com",
"emailId": "bulk_campaign_001",
"ip": "::1",
"userAgent": "Mozilla/5.0...",
"timestamp": "2025-07-12T14:30:00.000Z"
}
Benefits of This Approach
- Fully self-hosted and customizable
- Works with most email clients that allow image loading
- Easily extendable to track clicks, bounces, or unsubscribes
Limitations
Email opens can be blocked if:
- User disables images in their email client
- Apple Mail Privacy Protection hides IP and preloads images
- Some corporate firewalls may block external images
To increase accuracy, combine open tracking with click tracking and SMTP delivery webhooks.
Bonus: Extend for Click Tracking
Wrap all links in your email like this:
<a href="https://yourdomain.com/track/click?email=john@example.com&url=https%3A%2F%2Fexample.com">
Click Here
</a>
Then create a new route in server.js:
app.get('/track/click', async (req, res) => {
const { email, url } = req.query;
await EmailEvent.create({
type: 'click',
email,
clickedUrl: decodeURIComponent(url),
timestamp: new Date()
});
res.redirect(decodeURIComponent(url));
});
Folder Structure
email-tracker/
├── node_modules/
├── server.js
├── package.json
Final Thoughts
You now have a complete open tracking solution using Node.js and a tracking pixel. This is a great foundation for building advanced email analytics like:
- Open rate by campaign
- Unique opens
- Device/browser stats
- Click-through rate (CTR)
You can also integrate with tools like Google Analytics, SMTP webhooks, and dashboards to visualize data.

0 Comments