TourKit
@tour-kit/announcementsConfiguration

Audience Targeting

Target announcements to user segments with role-based, attribute, and custom predicate audience filtering rules

Audience Targeting

Target specific user segments with announcements. Only show messages to users who match your conditions.

Why Audience Targeting?

Send the right message to the right users:

  • Personalized - Show relevant announcements to specific user groups
  • Efficient - Don't waste impressions on irrelevant users
  • Contextual - Message users based on their plan, role, or behavior
  • Privacy-safe - All targeting happens client-side

User Context

Provide user information to the provider:

<AnnouncementsProvider
  userContext={{
    plan: 'pro',
    role: 'admin',
    signupDate: '2024-01-15',
    features: ['export', 'analytics'],
    customerId: '12345',
  }}
  announcements={announcements}
>
  <YourApp />
</AnnouncementsProvider>

The userContext object can contain any data you need for targeting.


Audience Conditions

Define conditions using the audience property:

{
  id: 'pro-feature',
  variant: 'modal',
  title: 'New Pro Feature',
  audience: [
    { field: 'plan', operator: 'equals', value: 'pro' },
  ],
}

Operators

Prop

Type


Examples

Plan-Based Targeting

// Show to free users only
{
  id: 'upgrade-promo',
  variant: 'banner',
  title: 'Upgrade to Pro',
  audience: [
    { field: 'plan', operator: 'equals', value: 'free' },
  ],
}

// Show to pro or enterprise users
{
  id: 'advanced-feature',
  variant: 'modal',
  title: 'New Advanced Analytics',
  audience: [
    { field: 'plan', operator: 'in', value: ['pro', 'enterprise'] },
  ],
}

Role-Based Targeting

// Show to admins only
{
  id: 'admin-dashboard',
  variant: 'slideout',
  title: 'New Admin Dashboard',
  audience: [
    { field: 'role', operator: 'equals', value: 'admin' },
  ],
}

// Show to non-admin users
{
  id: 'request-access',
  variant: 'toast',
  title: 'Need Admin Access?',
  audience: [
    { field: 'role', operator: 'notEquals', value: 'admin' },
  ],
}

Feature-Based Targeting

// Show if user has export feature
{
  id: 'export-update',
  variant: 'banner',
  title: 'Export Feature Improved',
  audience: [
    { field: 'features', operator: 'contains', value: 'export' },
  ],
}

// Show if user lacks analytics
{
  id: 'analytics-promo',
  variant: 'modal',
  title: 'Try Analytics',
  audience: [
    { field: 'features', operator: 'notContains', value: 'analytics' },
  ],
}

Date-Based Targeting

// Show to users who signed up after a date
{
  id: 'new-user-welcome',
  variant: 'modal',
  title: 'Welcome!',
  audience: [
    {
      field: 'signupDate',
      operator: 'greaterThan',
      value: '2024-01-01',
    },
  ],
}

Multiple Conditions

Combine multiple conditions (AND logic):

{
  id: 'trial-ending',
  variant: 'banner',
  title: 'Your Trial Ends Soon',
  audience: [
    { field: 'plan', operator: 'equals', value: 'trial' },
    { field: 'daysRemaining', operator: 'lessThan', value: 7 },
  ],
}

All conditions must match for the announcement to show.


Custom Conditions

Use custom functions for complex targeting:

<AnnouncementsProvider
  userContext={{ user }}
  announcements={[
    {
      id: 'custom-target',
      variant: 'modal',
      title: 'Special Offer',
      audience: [
        {
          type: 'custom',
          check: (context) => {
            // Custom logic
            const { user } = context;
            const isActiveUser = user.lastLogin > Date.now() - 86400000;
            const hasNoRecent Purchase = !user.lastPurchase;
            return isActiveUser && hasNoRecentPurchase;
          },
        },
      ],
    },
  ]}
/>

Custom Condition Type

type CustomCondition<T = any> = {
  type: 'custom';
  check: (context: T) => boolean;
};

OR Conditions

Create OR logic with multiple announcement configs:

const announcements = [
  // Show to free users
  {
    id: 'upgrade-promo-free',
    variant: 'banner',
    title: 'Upgrade to Pro',
    audience: [
      { field: 'plan', operator: 'equals', value: 'free' },
    ],
  },
  // OR show to trial users
  {
    id: 'upgrade-promo-trial',
    variant: 'banner',
    title: 'Upgrade to Pro',
    audience: [
      { field: 'plan', operator: 'equals', value: 'trial' },
    ],
  },
];

Or use the in operator:

{
  id: 'upgrade-promo',
  variant: 'banner',
  title: 'Upgrade to Pro',
  audience: [
    { field: 'plan', operator: 'in', value: ['free', 'trial'] },
  ],
}

Dynamic User Context

Update user context when user data changes:

function App() {
  const { user } = useAuth();

  return (
    <AnnouncementsProvider
      userContext={{
        plan: user.plan,
        role: user.role,
        features: user.features,
      }}
      announcements={announcements}
    >
      <YourApp />
    </AnnouncementsProvider>
  );
}

When userContext changes, the provider re-evaluates which announcements are eligible to show.


Programmatic Checks

Check if an announcement matches a user:

import { useAnnouncement } from '@tour-kit/announcements';

function ConditionalTrigger() {
  const announcement = useAnnouncement('pro-feature');

  // canShow checks both frequency rules AND audience targeting
  if (announcement.canShow) {
    return (
      <button onClick={announcement.show}>
        Learn About Pro Features
      </button>
    );
  }

  return null;
}

Use Cases

Trial Expiration

{
  id: 'trial-ending',
  variant: 'modal',
  title: 'Your Trial Expires in 3 Days',
  audience: [
    { field: 'plan', operator: 'equals', value: 'trial' },
    { field: 'trialDaysLeft', operator: 'lessThan', value: 4 },
  ],
  frequency: { type: 'interval', days: 1 },
  primaryAction: {
    label: 'Upgrade Now',
    onClick: () => router.push('/upgrade'),
  },
}

Feature Upsell

{
  id: 'analytics-upsell',
  variant: 'slideout',
  title: 'Unlock Analytics',
  description: 'Get insights into your data with our analytics package.',
  audience: [
    { field: 'features', operator: 'notContains', value: 'analytics' },
    { field: 'plan', operator: 'in', value: ['pro', 'enterprise'] },
  ],
  frequency: { type: 'times', count: 2 },
}

Onboarding for New Users

{
  id: 'welcome-tour',
  variant: 'modal',
  title: 'Welcome to Our Platform',
  audience: [
    {
      type: 'custom',
      check: (context) => {
        const signupDate = new Date(context.signupDate);
        const daysSinceSignup = (Date.now() - signupDate.getTime()) / 86400000;
        return daysSinceSignup < 7;
      },
    },
  ],
  frequency: 'once',
}

Behavior-Based

{
  id: 'power-user-feature',
  variant: 'spotlight',
  title: 'Try Advanced Mode',
  audience: [
    {
      type: 'custom',
      check: (context) => {
        // Show to users with high activity
        return context.actionsPerDay > 50;
      },
    },
  ],
  spotlightOptions: {
    target: '#advanced-toggle',
  },
}

Privacy Considerations

All audience targeting happens client-side. The userContext you provide is only used in the browser. No user data is sent to external services.

Best Practices

  • Only include necessary user data in userContext
  • Don't store sensitive information in announcement configs
  • Use custom conditions for complex privacy requirements
  • Consider using hashed or anonymized identifiers

Testing Audiences

Test Mode

<AnnouncementsProvider
  userContext={{ plan: 'free' }}
  announcements={announcements}
  debug={true} // Logs which announcements match
>

Manual Testing

// Test as free user
<AnnouncementsProvider userContext={{ plan: 'free' }}>

// Test as pro user
<AnnouncementsProvider userContext={{ plan: 'pro' }}>

// Test as admin
<AnnouncementsProvider userContext={{ role: 'admin' }}>

TypeScript

Type your user context for safety:

interface UserContext {
  plan: 'free' | 'pro' | 'enterprise';
  role: 'user' | 'admin';
  features: string[];
  signupDate: string;
  customerId: string;
}

const announcements: AnnouncementConfig<UserContext>[] = [
  {
    id: 'pro-feature',
    variant: 'modal',
    title: 'New Feature',
    audience: [
      // TypeScript knows 'plan' exists and its possible values
      { field: 'plan', operator: 'equals', value: 'pro' },
    ],
  },
];

<AnnouncementsProvider<UserContext>
  userContext={{
    plan: 'free',
    role: 'user',
    features: [],
    signupDate: '2024-01-15',
    customerId: '12345',
  }}
  announcements={announcements}
/>

On this page