Skip to Content
PlatformTargeting Rules

Targeting Rules

Targeting rules allow you to control which users see specific features or variations based on their attributes, behavior, and context. This enables precise feature delivery and personalized experiences.

What Are Targeting Rules?

Targeting rules are conditions that determine whether a user should receive a feature or variation. They evaluate user attributes against defined criteria to make targeting decisions.

import { DarkFeatureClient } from '@darkfeature/sdk-javascript' const client = new DarkFeatureClient({ apiKey: '1234567890abcdef1234567890abcdef', context: { userId: '123', email: '[email protected]', plan: 'premium', country: 'US', device: 'mobile', }, }) // The platform automatically evaluates targeting rules const isEnabled = await client.getFeature('premium-feature', { fallback: false, }) // Returns true if user.plan === 'premium'

Types of Targeting

1. User Attribute Targeting

Target based on user properties.

// Configure in dashboard to target premium users const targeting = { rules: [ { attribute: 'user.plan', operator: 'equals', value: 'premium', }, ], } // Configure in dashboard to target specific email domains const targeting = { rules: [ { attribute: 'user.email', operator: 'ends_with', value: '@company.com', }, ], }

2. Geographic Targeting

Target users by location.

// Configure in dashboard to target specific countries const targeting = { rules: [ { attribute: 'user.country', operator: 'in', value: ['US', 'CA', 'UK'], }, ], } // Configure in dashboard to target by region const targeting = { rules: [ { attribute: 'user.region', operator: 'equals', value: 'North America', }, ], }

3. Device Targeting

Target based on device characteristics.

// Configure in dashboard to target mobile users const targeting = { rules: [ { attribute: 'user.device', operator: 'equals', value: 'mobile', }, ], } // Configure in dashboard to target specific browsers const targeting = { rules: [ { attribute: 'user.browser', operator: 'in', value: ['chrome', 'firefox'], }, ], }

4. Behavioral Targeting

Target based on user behavior.

// Configure in dashboard to target new users const targeting = { rules: [ { attribute: 'user.signup_date', operator: 'greater_than', value: '2024-01-01', }, ], } // Configure in dashboard to target active users const targeting = { rules: [ { attribute: 'user.last_login', operator: 'greater_than', value: '2024-01-01', }, ], }

Targeting Operators

Comparison Operators

// Equals { attribute: 'user.plan', operator: 'equals', value: 'premium' } // Not equals { attribute: 'user.plan', operator: 'not_equals', value: 'free' } // Greater than { attribute: 'user.age', operator: 'greater_than', value: 18 } // Less than { attribute: 'user.age', operator: 'less_than', value: 65 } // Greater than or equal { attribute: 'user.purchase_count', operator: 'greater_than_or_equal', value: 5 } // Less than or equal { attribute: 'user.purchase_count', operator: 'less_than_or_equal', value: 10 }

String Operators

// Contains { attribute: 'user.email', operator: 'contains', value: 'admin' } // Starts with { attribute: 'user.email', operator: 'starts_with', value: 'test' } // Ends with { attribute: 'user.email', operator: 'ends_with', value: '@company.com' } // Regex match { attribute: 'user.email', operator: 'regex', value: '^admin@.*\\.com$' }

Array Operators

// In array { attribute: 'user.country', operator: 'in', value: ['US', 'CA', 'UK'] } // Not in array { attribute: 'user.country', operator: 'not_in', value: ['CN', 'RU'] } // Array contains { attribute: 'user.tags', operator: 'array_contains', value: 'premium' }

Using Targeting in Code

Basic Targeting

import { DarkFeatureClient } from '@darkfeature/sdk-javascript' const client = new DarkFeatureClient({ apiKey: '1234567890abcdef1234567890abcdef', context: { userId: '123', email: '[email protected]', plan: 'premium', country: 'US', }, }) // The platform automatically evaluates targeting rules const isEnabled = await client.getFeature('premium-features', { fallback: false, }) if (isEnabled) { showPremiumFeatures() } else { showBasicFeatures() }

Context Override

// Override context for specific requests const isEnabled = await client.getFeature('premium-features', { fallback: false, context: { plan: 'premium' }, })

Dynamic Context

// Update context based on user actions client.setContext({ userId: user.id, email: user.email, plan: user.plan, lastLogin: new Date().toISOString(), device: navigator.userAgent.includes('Mobile') ? 'mobile' : 'desktop', }) // All subsequent feature evaluations will use this context const isEnabled = await client.getFeature('mobile-optimized', { fallback: false, })

Multiple Features with Targeting

// Get multiple features with targeting const features = await client.getFeatures({ features: { 'premium-features': false, 'beta-features': false, 'mobile-optimized': false, }, context: { userId: '123', plan: 'premium', device: 'mobile', }, }) if (features['premium-features']) { showPremiumFeatures() } if (features['beta-features']) { showBetaFeatures() } if (features['mobile-optimized']) { applyMobileOptimizations() }

Advanced Targeting Patterns

Percentage Rollouts

// Configure percentage rollout in dashboard // The platform automatically handles percentage-based targeting const isEnabled = await client.getFeature('new-feature', { fallback: false }) if (isEnabled) { showNewFeature() } else { showOldFeature() }

Time-based Targeting

// Configure time-based rules in dashboard const isEnabled = await client.getFeature('holiday-promo', { fallback: false }) if (isEnabled) { showHolidayPromotion() }

Complex Conditional Logic

// Configure complex rules in dashboard const isEnabled = await client.getFeature('advanced-feature', { fallback: false, }) if (isEnabled) { showAdvancedFeature() }

React Integration

Basic Usage

import { DarkFeatureProvider, useFeature } from '@darkfeature/sdk-react' function App() { return ( <DarkFeatureProvider config={{ apiKey: '1234567890abcdef1234567890abcdef', context: { userId: '123', plan: 'premium', country: 'US', }, }}> <MyComponent /> </DarkFeatureProvider> ) } function MyComponent() { const { feature: isEnabled } = useFeature('premium-features', { fallback: false, }) return isEnabled ? <PremiumFeatures /> : <BasicFeatures /> }

Dynamic Context

import { useDarkFeatureContext } from '@darkfeature/sdk-react' function UserProfile() { const { updateContext, context } = useDarkFeatureContext() const handleUpgrade = () => { updateContext({ ...context, plan: 'premium', upgradeDate: new Date().toISOString(), }) } return ( <div> <h2>Current Plan: {context.plan || 'free'}</h2> <button onClick={handleUpgrade}>Upgrade to Premium</button> </div> ) }

Server-Side Targeting

Express.js Middleware

import express from 'express' import { DarkFeatureClient } from '@darkfeature/sdk-javascript' const app = express() const client = new DarkFeatureClient({ apiKey: process.env.DARKFEATURE_API_KEY, }) // Middleware to add feature flags with targeting app.use(async (req, res, next) => { const context = { userId: req.user?.id, email: req.user?.email, plan: req.user?.plan, country: req.get('CF-IPCountry'), // Cloudflare country header userAgent: req.get('User-Agent'), } req.features = await client.getFeatures({ features: { 'premium-features': false, 'beta-features': false, 'mobile-optimized': false, }, context, }) next() }) app.get('/api/data', async (req, res) => { if (req.features['premium-features']) { res.json({ data: 'premium-data', features: ['advanced', 'priority'] }) } else { res.json({ data: 'basic-data', features: ['standard'] }) } })

Fastify Plugin

import Fastify from 'fastify' import { DarkFeatureClient } from '@darkfeature/sdk-javascript' const fastify = Fastify() const client = new DarkFeatureClient({ apiKey: process.env.DARKFEATURE_API_KEY, }) // Plugin to add feature flags with targeting fastify.addHook('preHandler', async (request, reply) => { const context = { userId: request.user?.id, email: request.user?.email, plan: request.user?.plan, country: request.headers['cf-ipcountry'], userAgent: request.headers['user-agent'], } request.features = await client.getFeatures({ features: { 'premium-features': false, 'beta-features': false, }, context, }) }) fastify.get('/api/dashboard', async (request, reply) => { const data = { dashboard: 'basic' } if (request.features['premium-features']) { data.enhanced = true data.features = ['advanced-analytics', 'priority-support'] } return data })

Best Practices

Context Management

// Provide comprehensive user context const context = { userId: user.id, email: user.email, plan: user.plan, country: user.country, device: user.device, browser: user.browser, signupDate: user.signupDate, lastLogin: user.lastLogin, purchaseCount: user.purchaseCount, tags: user.tags, } client.setContext(context)

Testing Targeting Rules

// Test targeting rules with different contexts const testContexts = [ { plan: 'free', country: 'US' }, { plan: 'premium', country: 'US' }, { plan: 'premium', country: 'CA' }, { email: '[email protected]', plan: 'free' }, ] for (const context of testContexts) { const isEnabled = await client.getFeature('premium-features', { fallback: false, context, }) console.log(`Context: ${JSON.stringify(context)}, Enabled: ${isEnabled}`) }

Performance Optimization

// Cache targeting results when appropriate const cache = new Map() async function getFeatureWithCache(featureName, context, fallback = false) { const cacheKey = `${featureName}-${JSON.stringify(context)}` if (cache.has(cacheKey)) { return cache.get(cacheKey) } const result = await client.getFeature(featureName, { fallback, context }) cache.set(cacheKey, result) return result }

Error Handling

try { const isEnabled = await client.getFeature('premium-features', { fallback: false, }) // Use feature } catch (error) { console.error('Targeting evaluation error:', error) // Fallback to default behavior showDefaultFeatures() }

Next Steps

Last updated on