TourKit
@tour-kit/scheduling

@tour-kit/scheduling

Time-based scheduling for controlling when tours, announcements, and content appear — business hours, dates, and timezones

LLM Context File

Working with an AI assistant? Download the context file for @tour-kit/scheduling and paste it into your conversation for accurate code generation.

@tour-kit/scheduling

Time-based scheduling for tours, announcements, and onboarding content.

Why Scheduling Matters

Not all users should see tours at the same time. Scheduling helps you:

  • Launch at the right time - Show tours when features go live, not before
  • Respect user hours - Only display content during business hours or specific time zones
  • Avoid peak times - Block tours during critical periods like end-of-quarter
  • Target by region - Use timezone-aware scheduling for global audiences
  • Create recurring patterns - Show weekly tips or monthly feature highlights

Installation

pnpm add @tour-kit/scheduling

Quick Start

import { useSchedule } from '@tour-kit/scheduling'

function OnboardingTour() {
  const schedule = {
    startAt: '2024-01-15',
    endAt: '2024-03-31',
    daysOfWeek: [1, 2, 3, 4, 5], // Weekdays only
    timeOfDay: { start: '09:00', end: '17:00' },
    useUserTimezone: true,
  }

  const { isActive, reason } = useSchedule(schedule)

  if (!isActive) {
    return null
  }

  return <Tour tourId="onboarding">...</Tour>
}

Core Concepts

Schedule

A Schedule defines when content should be shown:

interface Schedule {
  enabled?: boolean
  startAt?: DateString | Date
  endAt?: DateString | Date
  daysOfWeek?: DayOfWeek[]
  timeOfDay?: TimeRange
  useUserTimezone?: boolean
  timezone?: string
  blackouts?: BlackoutPeriod[]
  recurring?: RecurringPattern
  metadata?: Record<string, unknown>
}

Evaluation Order

Schedules are evaluated in this order:

  1. Enabled check - Is enabled true?
  2. Date range - Is now between startAt and endAt?
  3. Blackout periods - Are we in a blackout?
  4. Day of week - Is today in daysOfWeek?
  5. Time of day - Is now in timeOfDay range?
  6. Business hours - Are we in business hours (if configured)?
  7. Recurring pattern - Does now match the pattern?

The first failed check determines the inactive reason.

Timezone Handling

All scheduling is timezone-aware:

// Use the user's browser timezone
const schedule = {
  useUserTimezone: true,
  timeOfDay: { start: '09:00', end: '17:00' },
}

// Or specify a fixed timezone
const schedule = {
  timezone: 'America/New_York',
  timeOfDay: { start: '09:00', end: '17:00' },
}

Dates are evaluated in the schedule's timezone, not UTC. This ensures users in different timezones see content at the correct local time.

Blackout Periods

Block specific date ranges regardless of other rules:

const schedule = {
  startAt: '2024-01-01',
  endAt: '2024-12-31',
  blackouts: [
    {
      id: 'holiday-freeze',
      start: '2024-12-20',
      end: '2024-12-31',
      reason: 'Holiday freeze',
    },
    {
      id: 'major-release',
      start: '2024-06-15T00:00:00Z',
      end: '2024-06-15T23:59:59Z',
      reason: 'Major product release',
    },
  ],
}

Blackouts override all other schedule rules.

Recurring Patterns

Show content on a repeating schedule:

// Every Monday and Wednesday
const schedule = {
  recurring: {
    type: 'weekly',
    daysOfWeek: [1, 3],
  },
}

// First day of each month
const schedule = {
  recurring: {
    type: 'monthly',
    dayOfMonth: 1,
  },
}

// Every 2 weeks, up to 5 occurrences
const schedule = {
  recurring: {
    type: 'weekly',
    interval: 2,
    maxOccurrences: 5,
  },
}

Package Structure

Hooks

React hooks for reactive scheduling:

Utilities

Pure functions for schedule evaluation:

Types

Full TypeScript definitions:

Presets

Built-in configurations:

Common Patterns

Weekdays Only

import { DAY_GROUPS } from '@tour-kit/scheduling'

const schedule = {
  daysOfWeek: DAY_GROUPS.weekdays, // [1, 2, 3, 4, 5]
}

Business Hours

import { BUSINESS_HOURS_PRESETS } from '@tour-kit/scheduling'

const schedule = {
  timeOfDay: BUSINESS_HOURS_PRESETS.standard.days[1].hours[0],
  // { start: '09:00', end: '17:00' }
}

Limited-Time Campaign

const schedule = {
  startAt: '2024-02-01',
  endAt: '2024-02-14',
  timeOfDay: { start: '08:00', end: '20:00' },
  useUserTimezone: true,
}

Recurring Weekly Tips

const schedule = {
  recurring: {
    type: 'weekly',
    daysOfWeek: [2], // Every Tuesday
    interval: 1,
    endDate: '2024-12-31',
  },
}

Next Steps

On this page