@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/schedulingQuick 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:
- Enabled check - Is
enabledtrue? - Date range - Is now between
startAtandendAt? - Blackout periods - Are we in a blackout?
- Day of week - Is today in
daysOfWeek? - Time of day - Is now in
timeOfDayrange? - Business hours - Are we in business hours (if configured)?
- 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:
useSchedule- Simple active/inactive checkuseScheduleStatus- Detailed status with next active/inactive timesuseUserTimezone- Get user's browser timezone
Utilities
Pure functions for schedule evaluation:
- Evaluation -
checkSchedule,isScheduleActive,getScheduleStatus - Timezone -
getUserTimezone,isValidTimezone,formatDateString - Date Range -
isWithinDateRange - Time Range -
isWithinTimeRange,isWithinAnyTimeRange - Day of Week -
getDayOfWeek,isAllowedDay - Blackouts -
isInBlackoutPeriod,getCurrentBlackout - Business Hours -
isWithinBusinessHours,isHoliday - Recurring -
matchesRecurringPattern
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
- useSchedule Hook - Start using reactive scheduling
- Schedule Evaluation - Understand how schedules are evaluated
- Types Reference - Explore all available types