Callbacks for Remix
NextStep provides a powerful callbacks system that allows you to execute custom code at various points during a tour. This enables you to create dynamic, interactive tours that respond to user actions.
Available Callbacks
NextStep supports the following callbacks that you can use to customize your tour behavior:
onStart
Called when a tour starts. Receives the tour name as a parameter.
onStart: (tourName: string | null) => {
console.log(`Tour ${tourName} started`);
// Track analytics, set user state, etc.
}
onComplete
Called when a tour is completed. Receives the tour name as a parameter.
onComplete: (tourName: string | null) => {
console.log(`Tour ${tourName} completed`);
// Update user preferences, show completion message, etc.
}
onSkip
Called when a user skips a tour. Receives the step index and tour name as parameters.
onSkip: (step: number, tourName: string | null) => {
console.log(`Tour ${tourName} skipped at step ${step}`);
// Log skip event, offer to resume later, etc.
}
onStepChange
Called when the current step changes. Receives the step index and tour name as parameters.
onStepChange: (step: number, tourName: string | null) => {
console.log(`Tour ${tourName} moved to step ${step}`);
// Update UI, trigger animations, etc.
}
Using Callbacks
You can provide callbacks when initializing the NextStep component:
// In your root component
import { NextStepProvider, NextStepReact } from 'nextstepjs';
import steps from './steps';
function App() {
return (
<NextStepProvider>
<NextStepReact
steps={steps}
onStart={(tourName) => {
console.log(`Tour ${tourName} started`);
}}
onComplete={(tourName) => {
console.log(`Tour ${tourName} completed`);
}}
onSkip={(step, tourName) => {
console.log(`Tour ${tourName} skipped at step ${step}`);
}}
onStepChange={(step, tourName) => {
console.log(`Step changed to ${step} in ${tourName}`);
}}
>
<YourAppContent />
</NextStepReact>
</NextStepProvider>
);
}
Practical Examples
Tracking User Progress
Use callbacks to track user progress through your onboarding tour:
// Track user progress with analytics
const trackProgress = {
onStart: (tourName) => {
analytics.track('tour_started', { tourName });
},
onStepChange: (step, tourName) => {
analytics.track('tour_step_viewed', {
tourName,
stepIndex: step,
stepName: `${tourName}_step_${step}`
});
},
onComplete: (tourName) => {
analytics.track('tour_completed', { tourName });
// Update user profile to mark onboarding as complete
updateUserProfile({ onboardingComplete: true });
},
onSkip: (step, tourName) => {
analytics.track('tour_skipped', { tourName, stepIndex: step });
}
};
// Then use it in your NextStep component
<NextStepReact
steps={steps}
{...trackProgress}
>
{children}
</NextStepReact>
Form Validation
Use the onStepChange
callback to validate form inputs when a user moves to a new step:
// Form validation when step changes
const formValidation = {
onStepChange: (step, tourName) => {
// Validate the previous step's inputs
if (step === 2 && tourName === 'onboardingTour') {
const usernameField = document.getElementById('username');
if (!usernameField || !usernameField.value) {
// Log validation failure
console.warn('Username field was not completed');
}
}
if (step === 3 && tourName === 'onboardingTour') {
const emailField = document.getElementById('email');
if (!emailField || !validateEmail(emailField.value)) {
// Log validation failure
console.warn('Email field was not completed or is invalid');
}
}
}
};
// Then use it in your NextStep component
<NextStepReact
steps={steps}
{...formValidation}
>
{children}
</NextStepReact>
Dynamic Content
Use the onStepChange
callback to update UI elements based on the current step:
// Dynamic content based on current step
const [highlightedSection, setHighlightedSection] = useState(null);
const dynamicContent = {
onStepChange: (step, tourName) => {
// Update UI based on the current step
if (tourName === 'featureTour') {
switch(step) {
case 0:
setHighlightedSection('dashboard');
break;
case 1:
setHighlightedSection('sidebar');
break;
case 2:
setHighlightedSection('settings');
break;
default:
setHighlightedSection(null);
}
}
},
onComplete: () => {
// Reset UI when tour ends
setHighlightedSection(null);
},
onSkip: () => {
// Reset UI when tour is skipped
setHighlightedSection(null);
}
};
// Then use it in your NextStep component
<NextStepReact
steps={steps}
{...dynamicContent}
>
{children}
</NextStepReact>
Note: Callbacks must be defined in a client component. Ensure that your component is using 'use client' at the top.