If your organisation’s privacy policy does not allow the collection or processing of user IP addresses, SegmentStream supports an alternative setup.
Instead of sending raw IP addresses, you can hash the IP (with salt) and enrich it with geolocation data on your side, before passing it to the SegmentStream data layer.
This approach ensures:
- No personally identifiable IP data is shared with SegmentStream.
- You still provide necessary contextual information (such as country, city, or region).
- Compliance with stricter data protection requirements (e.g. GDPR).
1. Required fields in the data layer
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'user_context',
ip_hash: '1e4b9f1a3d7e... (hashed and salted value)',
country: 'DE',
region: 'Berlin',
city: 'Berlin',
});
Field descriptions
| Field | Type | Description |
|---|
ip_hash | string | Hashed (and salted) IP address. The hash ensures anonymity, and the salt prevents reverse-engineering. |
country | string | Country code (e.g. "DE", "FR", "US"). |
region | string | Region or state. |
city | string | City name. |
2. How to prepare the IP address
All processing, including normalisation and hashing, should happen on your server. This ensures the raw IP address never leaves your infrastructure and that only anonymised data is shared with SegmentStream.
Step 1: Normalise IPv6 addresses (server-side)
IPv6 addresses are more detailed than IPv4 and can include device-specific parts. To ensure privacy, the IPv6 address should be normalised to keep only the network portion (the first half) and replace the device-specific bits with zeros.
| Type | IPv6 example | Meaning |
|---|
| Full IPv6 | 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | Device-level identifier |
| Normalised | 2001:0db8:85a3:0000:0000:0000:0000:0000 | Network-level identifier (safe to hash) |
// Run on your backend
function normalizeIPv6(ip) {
if (!ip.includes(':')) return ip; // IPv4 - no normalization
const segments = ip.split(':').slice(0, 4);
while (segments.length < 8) segments.push('0000');
return segments.join(':');
}
If the IP is IPv4, you can skip this step.
Step 2: Apply salted hashing (server-side)
After normalisation, hash the IP using a secure algorithm like SHA-256 and a private salt stored safely on your backend (e.g. in environment variables).
- Do not hash or salt IPs in the browser.
- The salt must remain secret and never be exposed to the client.
- Only send the hashed IP and geo data to the frontend.
import crypto from 'crypto';
const SALT = process.env.IP_HASH_SALT; // store securely in environment variables
function hashIP(ip) {
return crypto.createHash('sha256').update(ip + SALT).digest('hex');
}
Example output:
f2c992f0a9f8d5c8b87e1a2b36a52e5bce9df51de60cdb3eaf5d66a6dfdfe281
Step 3: Example of each stage
| Step | Description | Example |
|---|
| Full IPv6 | Original address | 2001:0db8:85a3:0000:0000:8a2e:0370:7334 |
| Normalised | Network-only portion (safe to hash) | 2001:0db8:85a3:0000:0000:0000:0000:0000 |
| Hashed (with salt) | Final anonymised value | f2c992f0a9f8d5c8b87e1a2b36a52e5bce9df51... |
3. Geolocation data
Use your own geolocation service (e.g. MaxMind, IP2Location, or a cloud provider’s API) to extract country and region information before hashing.
4. Example architecture
Below is a complete setup showing where each process occurs.
Server (Node.js / Python / etc.)
app.get('/api/user-context', async (req, res) => {
const ip = getClientIP(req); // your logic for IP extraction
const normalized = normalizeIPv6(ip);
const hashed = hashIP(normalized);
const geo = await lookupGeo(ip); // from your geolocation provider
res.json({
ip_hash: hashed,
country: geo.country,
region: geo.region,
city: geo.city,
});
});
Client (browser)
(async () => {
const context = await fetch('/api/user-context').then(r => r.json());
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'user_context',
ip_hash: context.ip_hash,
country: context.country,
region: context.region,
city: context.city,
});
})();
This way:
- The raw IP never leaves your infrastructure.
- The client receives only anonymised and geo-enriched data.
- SegmentStream operates in full privacy compliance.
5. Summary checklist