# Product Tours

Product tours are guided walkthroughs that help users discover features and learn your application. Tours can include modal dialogs, element highlights, tooltips, and surveys to create interactive onboarding experiences.

## Capabilities

### Get All Product Tours

Fetches all product tours configured in your PostHog project.

```typescript { .api }
/**
 * Gets all product tours from the server
 * @param callback - Callback receiving tours and load status
 * @param forceReload - Force reload from server instead of using cache
 */
function getProductTours(
    callback: ProductTourCallback,
    forceReload?: boolean
): void;
```

**Usage Examples:**

```typescript
// Get all tours
posthog.productTours.getProductTours((tours, context) => {
    if (context.isLoaded) {
        console.log('All tours:', tours);
        tours.forEach(tour => {
            console.log(`Tour: ${tour.name}, Status: ${tour.display_frequency}`);
        });
    } else {
        console.error('Failed to load tours:', context.error);
    }
});

// Force reload from server
posthog.productTours.getProductTours((tours, context) => {
    console.log('Fresh tours:', tours);
}, true);
```

### Get Active Product Tours

Fetches product tours that should be shown to the current user based on targeting conditions and display rules.

```typescript { .api }
/**
 * Gets active product tours matching current user and conditions
 * @param callback - Callback receiving active tours and load status
 */
function getActiveProductTours(callback: ProductTourCallback): void;
```

**Usage Examples:**

```typescript
// Get tours for current user
posthog.productTours.getActiveProductTours((tours, context) => {
    if (context.isLoaded && tours.length > 0) {
        console.log('Active tours:', tours);
        // Automatically show the first active tour
        posthog.productTours.showProductTour(tours[0].id);
    }
});
```

### Show Product Tour

Displays a specific product tour by its ID.

```typescript { .api }
/**
 * Shows a product tour by its ID
 * @param tourId - Unique identifier for the tour
 */
function showProductTour(tourId: string): void;
```

**Usage Examples:**

```typescript
// Show specific tour
posthog.productTours.showProductTour('tour-abc-123');

// Show tour on button click
button.addEventListener('click', () => {
    posthog.productTours.showProductTour('onboarding-tour');
});

// Conditional tour display
if (isNewUser) {
    posthog.productTours.showProductTour('welcome-tour');
}
```

## Configuration

Product tours are disabled by default and must be enabled in initialization:

```typescript
posthog.init('<your-project-api-key>', {
    disable_product_tours: false // Enable product tours
});
```

## Types

### ProductTourCallback

```typescript { .api }
/**
 * Callback invoked when product tours are loaded
 * @param tours - Array of product tours
 * @param context - Load status and error information
 */
type ProductTourCallback = (
    tours: ProductTour[],
    context: { isLoaded: boolean; error?: string }
) => void;
```

### ProductTour

```typescript { .api }
/**
 * Product tour definition
 */
interface ProductTour {
    /**
     * Unique tour identifier
     */
    id: string;

    /**
     * Tour name
     */
    name: string;

    /**
     * Tour description
     */
    description?: string;

    /**
     * Display frequency control
     * - 'once': Show once per user
     * - 'multiple': Show multiple times
     */
    display_frequency: 'once' | 'multiple';

    /**
     * Tour steps
     */
    steps: ProductTourStep[];

    /**
     * Visual appearance configuration
     */
    appearance?: ProductTourAppearance;

    /**
     * Conditions for showing the tour
     */
    conditions?: ProductTourConditions;
}
```

### ProductTourStep

```typescript { .api }
/**
 * Individual step in a product tour
 */
interface ProductTourStep {
    /**
     * Step type
     * - 'element': Highlight and describe a page element
     * - 'modal': Show a modal dialog
     * - 'survey': Show a survey question
     * - 'banner': Show a banner message
     */
    type: 'element' | 'modal' | 'survey' | 'banner';

    /**
     * Step title
     */
    title?: string;

    /**
     * Step content/description
     */
    content?: string;

    /**
     * CSS selector for element to highlight (element type only)
     */
    selector?: string;

    /**
     * Button text
     */
    buttonText?: string;

    /**
     * Survey configuration (survey type only)
     */
    survey?: {
        question: string;
        type: 'open' | 'multiple_choice' | 'rating';
        choices?: string[];
    };
}
```

### ProductTourAppearance

```typescript { .api }
/**
 * Visual styling for product tours
 */
interface ProductTourAppearance {
    /**
     * Primary color
     */
    primaryColor?: string;

    /**
     * Background color
     */
    backgroundColor?: string;

    /**
     * Text color
     */
    textColor?: string;

    /**
     * Border radius
     */
    borderRadius?: number;

    /**
     * Positioning
     */
    position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
}
```

### ProductTourConditions

```typescript { .api }
/**
 * Conditions for showing a product tour
 */
interface ProductTourConditions {
    /**
     * URL patterns where tour should show
     */
    urlPatterns?: string[];

    /**
     * Feature flags that must be enabled
     */
    featureFlags?: string[];

    /**
     * User properties that must match
     */
    userProperties?: Record<string, any>;

    /**
     * Minimum time after user signup (seconds)
     */
    minSecondsSinceSignup?: number;
}
```

## Best Practices

### Tour Timing

```typescript
// Wait for app to be ready before checking for tours
window.addEventListener('load', () => {
    posthog.productTours.getActiveProductTours((tours) => {
        if (tours.length > 0) {
            // Show first tour after a small delay
            setTimeout(() => {
                posthog.productTours.showProductTour(tours[0].id);
            }, 1000);
        }
    });
});
```

### User Onboarding

```typescript
// Show different tours based on user stage
posthog.onFeatureFlags((flags) => {
    const userStage = posthog.get_property('onboarding_stage');

    if (userStage === 'new') {
        posthog.productTours.showProductTour('welcome-tour');
    } else if (userStage === 'learning') {
        posthog.productTours.showProductTour('advanced-features-tour');
    }
});
```

### Progressive Tours

```typescript
// Show tours sequentially
let currentTourIndex = 0;
const tourIds = ['tour-1', 'tour-2', 'tour-3'];

function showNextTour() {
    if (currentTourIndex < tourIds.length) {
        posthog.productTours.showProductTour(tourIds[currentTourIndex]);
        currentTourIndex++;
    }
}

// Start first tour
showNextTour();
```

## Common Patterns

### Conditional Tour Display

```typescript
// Show tour based on user properties
posthog.getActiveProductTours((tours, context) => {
    if (context.isLoaded) {
        const userPlan = posthog.get_property('plan');

        tours.forEach(tour => {
            // Show premium tours only to premium users
            if (tour.name.includes('premium') && userPlan === 'premium') {
                posthog.productTours.showProductTour(tour.id);
            }
        });
    }
});
```

### Feature Introduction Tours

```typescript
// Show tour when new feature is enabled
posthog.onFeatureFlags((flags) => {
    if (flags['new-feature'] && !posthog.get_property('seen-new-feature-tour')) {
        posthog.productTours.showProductTour('new-feature-tour');
        posthog.register({ 'seen-new-feature-tour': true });
    }
});
```

### Manual Tour Trigger

```typescript
// Add a help button to manually show tours
function HelpButton() {
    return (
        <button onClick={() => {
            posthog.productTours.getActiveProductTours((tours) => {
                if (tours.length > 0) {
                    // Show first available tour
                    posthog.productTours.showProductTour(tours[0].id);
                } else {
                    console.log('No tours available');
                }
            });
        }}>
            Show Help Tour
        </button>
    );
}
```
