How to Block or Segment Visitors by IP Address in Your Experiments
🚫 Control content visibility by filtering visitor access using IP-based targeting with JavaScript and Convert Experiences
🚀 IN THIS ARTICLE YOU WILL:
In some scenarios, you may need to restrict or customize content for visitors based on their IP addresses. This article shows how to implement IP-based visitor filtering in Convert Experiences using a modern approach that properly integrates with Convert's experiment lifecycle.
⚙️ Setting Up IP-Based Filtering
1. Adding the JavaScript Code
Insert the following JavaScript code into the Global JavaScript section of your project:
// Step 1: Fetch the IP and wait for it
function getVisitorIP() {
return new Promise((resolve, reject) => {
fetch('https://ipapi.co/json/')
.then(response => response.json())
.then(data => {
resolve(data.ip);
})
.catch(error => {
console.error('Error fetching IP:', error);
reject(error);
});
});
}
// Configuration for IP lists
const config = {
mode: 'blacklist', // or 'whitelist'
ipList: [
'123.456.789.012', // Single IP
'192.168.1.0/24', // CIDR notation
'10.0.0.1-10.0.0.255' // Range notation
],
showExperiences: false // Flag that will be set based on IP check
};
// Step 2 & 3: Check if IP is within Allow/Disallow List and set flag
function checkIPAccess(ip) {
// Check if IP matches any entry in the list
const ipMatch = config.ipList.some(entry => {
// Check if entry is a single IP
if (!entry.includes('/') && !entry.includes('-')) {
return ip === entry;
}
// Check if entry is in CIDR notation
else if (entry.includes('/')) {
return isIPInCIDR(ip, entry);
}
// Check if entry is in range notation
else if (entry.includes('-')) {
const [start, end] = entry.split('-');
return isIPInRange(ip, start, end);
}
return false;
});
// Set the flag based on mode and whether IP matched
if (config.mode === 'whitelist') {
config.showExperiences = ipMatch;
} else { // blacklist mode
config.showExperiences = !ipMatch;
}
return config.showExperiences;
}
// Helper function to check if IP is within a range
function isIPInRange(ip, rangeStart, rangeEnd) {
const ipNum = ipToNumber(ip);
const startNum = ipToNumber(rangeStart);
const endNum = ipToNumber(rangeEnd);
return ipNum >= startNum && ipNum <= endNum;
}
// Helper function to check if IP is within a CIDR range
function isIPInCIDR(ip, cidr) {
const [subnet, bits] = cidr.split('/');
const ipNum = ipToNumber(ip);
const subnetNum = ipToNumber(subnet);
const mask = -1 << (32 - parseInt(bits));
return (ipNum & mask) === (subnetNum & mask);
}
// Helper function to convert IP to number for comparison
function ipToNumber(ip) {
return ip.split('.')
.map((octet, index) => parseInt(octet) * Math.pow(256, 3 - index))
.reduce((sum, num) => sum + num, 0);
}
// Initialize and handle experiment execution
function initializeIPBasedExperiments() {
let visitorIP;
// Fetch the IP first
getVisitorIP().then(ip => {
visitorIP = ip;
const shouldShowExperiments = checkIPAccess(ip);
console.log('IP check result:', shouldShowExperiments ? 'Allow' : 'Block');
// Wait for Convert to complete its initial evaluation
document.addEventListener('convert:executed', function() {
console.log('Initial experiment evaluation completed');
// Based on our IP check, decide if we need to re-run experiments
if (!shouldShowExperiments) {
console.log('Re-running experiments with IP-based restrictions');
window._conv_q = window._conv_q || [];
window._conv_q.push({what: 'run'});
}
},{ once: true }); // Only trigger this once for the initial execution
}).catch(error => {
console.error('Failed to initialize IP-based experiments:', error);
// Fallback behavior in case of error
config.showExperiences = false; // Default to showing experiences if IP check fails
});
}
// Start the process
initializeIPBasedExperiments();
2. Configuring IP Lists
You can configure the script by modifying the config
object:
-
Set
mode
to either'blacklist'
(block specified IPs) or'whitelist'
(allow only specified IPs) -
Add IP addresses to the
ipList
array using any of these formats:-
Single IP:
'192.168.1.1'
-
CIDR notation:
'192.168.1.0/24'
-
IP Range:
'10.0.0.1-10.0.0.255'
-
3. Integrating with Experiments
With this code in place, you do not need additional JavaScript conditions in your experiment audiences. The script will:
-
Fetch the visitor’s IP address
-
Check if it matches your configured IP rules
-
Let Convert run its initial evaluation
-
Based on the IP check, potentially re-run experiments with the appropriate restrictions
✅ This approach ensures that your IP-based rules are applied consistently across all experiments without falling into evaluation loops.
🛠️ Debugging Tips
To verify the functionality:
-
Open your browser’s developer console
-
Check the logs which will show:
-
The result of the IP check (Allow or Block)
-
When the initial experiment evaluation completes
-
If experiments are being re-run due to IP restrictions
-
-
You can also type
config.showExperiences
in the console to see the current state of the IP-based flag.