Next.js App Router Adapter
Next.js App Router adapter: configure route-aware tours with usePathname integration for server component layouts
Router adapter for Next.js 13+ App Router using next/navigation.
When to Use
Use this adapter when:
- You're using Next.js 13 or later
- Your app uses the App Router (
app/directory) - You need multi-page tours that navigate between routes
Installation
The adapter is included in @tour-kit/react. Make sure Next.js is installed:
pnpm add @tour-kit/react nextUsage
'use client';
import { MultiTourKitProvider, useNextAppRouter } from '@tour-kit/react';
export function TourProvider({ children }: { children: React.ReactNode }) {
const router = useNextAppRouter();
return (
<MultiTourKitProvider
router={router}
routePersistence={{ enabled: true }}
>
{children}
</MultiTourKitProvider>
);
}'use client';
import { MultiTourKitProvider, createNextAppRouterAdapter } from '@tour-kit/react';
import { usePathname, useRouter } from 'next/navigation';
const useRouter = createNextAppRouterAdapter(usePathname, useRouter);
export function TourProvider({ children }: { children: React.ReactNode }) {
const router = useRouter();
return (
<MultiTourKitProvider
router={router}
routePersistence={{ enabled: true }}
>
{children}
</MultiTourKitProvider>
);
}Both the adapter hook and any component using it must have 'use client' at the top since they use browser APIs and React hooks.
useNextAppRouter
Direct hook that automatically imports from next/navigation.
import { useNextAppRouter } from '@tour-kit/react';
const router = useNextAppRouter();Return Value
Returns a RouterAdapter with these methods:
Prop
Type
createNextAppRouterAdapter
Factory function for custom setups.
import { createNextAppRouterAdapter } from '@tour-kit/react';
import { usePathname, useRouter } from 'next/navigation';
const useMyRouter = createNextAppRouterAdapter(usePathname, useRouter);Parameters
Prop
Type
Complete Example
'use client';
import {
MultiTourKitProvider,
useNextAppRouter,
Tour,
TourStep,
TourOverlay,
TourCard,
useTour,
} from '@tour-kit/react';
export function TourProvider({ children }: { children: React.ReactNode }) {
const router = useNextAppRouter();
return (
<MultiTourKitProvider
router={router}
routePersistence={{
enabled: true,
storage: 'localStorage',
expiryMs: 24 * 60 * 60 * 1000, // 24 hours
}}
autoNavigate={true}
onTourComplete={(tourId) => {
console.log(`Tour ${tourId} completed!`);
}}
>
<Tour id="onboarding">
<TourStep
target="#hero-section"
title="Welcome!"
content="Let's show you around our app."
route="/"
routeMatch="exact"
/>
<TourStep
target="#dashboard-widget"
title="Your Dashboard"
content="View your metrics and activity here."
route="/dashboard"
routeMatch="startsWith"
/>
<TourStep
target="#settings-link"
title="Settings"
content="Customize your experience in settings."
route="/settings"
/>
</Tour>
<TourOverlay />
<TourCard />
{children}
<TourButton />
</MultiTourKitProvider>
);
}
function TourButton() {
const { start, isActive } = useTour();
if (isActive) return null;
return (
<button
onClick={() => start('onboarding')}
className="fixed bottom-4 right-4 px-4 py-2 bg-blue-500 text-white rounded-lg"
>
Start Tour
</button>
);
}import { TourProvider } from './providers/tour-provider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<TourProvider>
{children}
</TourProvider>
</body>
</html>
);
}SSR Handling
The adapter handles SSR gracefully:
usePathname()may returnnullduring SSR edge cases - adapter defaults to'/'- Route change callbacks only fire client-side
- Initial route is detected after hydration
Route Change Detection
The adapter uses usePathname() reactivity to detect route changes:
// Internal behavior:
useEffect(() => {
if (previousPath !== pathname) {
for (const callback of callbacks) {
callback(pathname);
}
}
}, [pathname]);The onRouteChange callback fires immediately with the current route when subscribed, then on each subsequent navigation.
Troubleshooting
"Cannot find module 'next/navigation'"
The adapter requires Next.js 13+. Check your Next.js version:
npm list nextHydration Mismatch
Ensure tour components have 'use client':
'use client'; // Required!
import { Tour } from '@tour-kit/react';Routes Not Matching
Check your routeMatch mode:
// For exact paths
<TourStep route="/" routeMatch="exact" />
// For paths with dynamic segments
<TourStep route="/dashboard" routeMatch="startsWith" />Related
- Next.js Integration Guide - Complete setup walkthrough
- Router Adapters Overview - All available adapters
- MultiTourKitProvider - Provider configuration