@tour-kit/reactHooks
useTourRoute
useTourRoute hook: synchronize tour progress with router state for multi-page tours in Next.js and React Router
domidex01Published
Hook for route-aware tour operations. Provides utilities for checking if the current step is on the current route and navigating to the correct route.
Why Use This Hook?
Multi-page tours need to handle route mismatches:
- Detect route mismatches - Know when step's route differs from current
- Navigate to step route - Programmatically go to the correct page
- Check route state - Determine if navigation is in progress
- Match routes flexibly - Use exact, prefix, or contains matching
Usage
import { useTourRoute, useNextAppRouter, useTour } from '@tour-kit/react';
function TourCard() {
const router = useNextAppRouter();
const { currentStep } = useTour();
const {
isStepOnCurrentRoute,
currentStepRoute,
goToStepRoute,
isNavigating,
} = useTourRoute({ router });
// If step requires different route, show navigation prompt
if (!isStepOnCurrentRoute) {
return (
<div className="p-4 bg-yellow-100 rounded">
<p>This step is on a different page.</p>
<button
onClick={goToStepRoute}
disabled={isNavigating}
className="mt-2 btn-primary"
>
{isNavigating ? 'Navigating...' : `Go to ${currentStepRoute}`}
</button>
</div>
);
}
// Normal tour card
return (
<div className="p-4 bg-white rounded shadow">
<h3>{currentStep?.title}</h3>
<p>{currentStep?.content}</p>
</div>
);
}Parameters
Prop
Type
Return Value
Prop
Type
Route Matching
Steps without a route prop are considered valid on any route:
// Always matches (no route specified)
<TourStep target="#element" title="Always Here" />
// Only matches exact path
<TourStep target="#home" route="/" routeMatch="exact" />
// Matches path prefix
<TourStep target="#dashboard" route="/dashboard" routeMatch="startsWith" />The hook uses the step's routeMatch mode:
const { isStepOnCurrentRoute } = useTourRoute({ router });
// If step has route="/dashboard" and routeMatch="startsWith"
// isStepOnCurrentRoute = true for /dashboard, /dashboard/settings, etc.Examples
Route Mismatch Overlay
function RouteMismatchOverlay() {
const router = useNextAppRouter();
const { isStepOnCurrentRoute, currentStepRoute, goToStepRoute } = useTourRoute({ router });
if (isStepOnCurrentRoute) return null;
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
<div className="bg-white p-6 rounded-lg max-w-md">
<h3 className="text-lg font-bold">Wrong Page</h3>
<p className="mt-2 text-gray-600">
This tour step is on a different page.
</p>
<div className="mt-4 flex gap-2">
<button
onClick={goToStepRoute}
className="px-4 py-2 bg-blue-500 text-white rounded"
>
Go to {currentStepRoute}
</button>
</div>
</div>
</div>
);
}Breadcrumb with Route Status
function TourBreadcrumb() {
const router = useNextAppRouter();
const { currentRoute, isOnRoute } = useTourRoute({ router });
const routes = ['/', '/dashboard', '/settings'];
return (
<nav className="flex gap-2">
{routes.map(route => (
<span
key={route}
className={isOnRoute(route, 'startsWith') ? 'text-blue-500' : 'text-gray-400'}
>
{route}
</span>
))}
</nav>
);
}Auto-Navigate on Step Change
function AutoNavigator() {
const router = useNextAppRouter();
const { isStepOnCurrentRoute, goToStepRoute } = useTourRoute({ router });
const { currentStepIndex } = useTour();
useEffect(() => {
if (!isStepOnCurrentRoute) {
goToStepRoute();
}
}, [currentStepIndex, isStepOnCurrentRoute, goToStepRoute]);
return null; // Invisible component
}If autoNavigate={true} is set on MultiTourKitProvider, navigation happens automatically. Use this hook for custom navigation UX.
With Specific Tour
Access route info for a specific tour (not just the active one):
function SpecificTourRoute() {
const router = useNextAppRouter();
// Check route for 'onboarding' tour specifically
const { currentStepRoute } = useTourRoute({
router,
tourId: 'onboarding',
});
return <p>Onboarding step route: {currentStepRoute}</p>;
}Navigation States
function NavigationAwareCard() {
const router = useNextAppRouter();
const { isNavigating, goToStepRoute, isStepOnCurrentRoute } = useTourRoute({ router });
return (
<div>
{isNavigating && <LoadingSpinner />}
{!isStepOnCurrentRoute && !isNavigating && (
<button onClick={goToStepRoute}>
Navigate to Step
</button>
)}
{isStepOnCurrentRoute && <TourCardContent />}
</div>
);
}Related
- Router Adapters - Router adapter options
- MultiTourKitProvider - autoNavigate setting
- useRoutePersistence - Persist state across routes