NextStep - Lightweight Next.js Onboarding Library Logo

Routing During Tours for Next.js

One of the most powerful features of NextStep is the ability to navigate between different pages during a tour. This guide explains how to set up routing in your Next.js application.

Navigation Adapters

NextStep uses navigation adapters to handle routing in different frameworks. These adapters ensure that your tours can seamlessly transition between pages.

Next.js Navigation Adapter

For Next.js, the navigation adapter is built-in and automatically used when you use the NextStep component. You don't need to specify it explicitly.

// In your layout.tsx or app.tsx
import { NextStepProvider, NextStep } from 'nextstepjs';
import steps from '@/lib/steps';

export default function RootLayout({ children }) {
  return (
    <NextStepProvider>
      <NextStep steps={steps}>
        {children}
      </NextStep>
    </NextStepProvider>
  );
}

Creating a Custom Navigation Adapter

If you're using a different routing library or need custom navigation behavior, you can create your own navigation adapter. A navigation adapter is a hook that returns an object with navigate and location properties.

// customNavigationAdapter.ts
import { useCallback, useEffect, useState } from 'react';
import { NavigationAdapter } from 'nextstepjs';

export function useCustomNavigationAdapter(): NavigationAdapter {
  const [location, setLocation] = useState(window.location.pathname);

  // Update location when the URL changes
  useEffect(() => {
    const handleLocationChange = () => {
      setLocation(window.location.pathname);
    };

    window.addEventListener('popstate', handleLocationChange);
    return () => {
      window.removeEventListener('popstate', handleLocationChange);
    };
  }, []);

  // Custom navigation function
  const navigate = useCallback((to: string) => {
    window.history.pushState({}, '', to);
    setLocation(to);
  }, []);

  return { navigate, location };
}

Then use your custom adapter with NextStepReact:

import { useCustomNavigationAdapter } from './customNavigationAdapter';

// In your root component
<NextStep 
  steps={steps} 
  navigationAdapter={useCustomNavigationAdapter}
>
  <YourAppContent />
</NextStep>

Routing During Tours

To enable routing during tours, you can add nextRoute and prevRoute properties to your step objects:

// In your steps.tsx file
{
  tour: 'routingDemo',
  steps: [
    {
      icon: <>👋</>,
      title: 'Welcome to Page One',
      content: <>This is the first step. Click next to go to page two.</>,
      selector: '#page-one-element',
      side: 'bottom',
      showControls: true,
      showSkip: true,
      // Navigate to page two when clicking "Next"
      nextRoute: '/page-two',
    },
    {
      icon: <>🎉</>,
      title: 'Welcome to Page Two',
      content: <>This is the second step. Click previous to go back to page one.</>,
      selector: '#page-two-element',
      side: 'bottom',
      showControls: true,
      showSkip: true,
      // Navigate back to page one when clicking "Previous"
      prevRoute: '/page-one',
    },
  ],
}

Note: When using nextRoute and prevRoute, NextStep will first navigate to the specified route and then show the next/previous step. This allows you to create tours that span multiple pages.

Interactive Demo

Try out the routing demo below. This demo will navigate between the homepage and this page during the tour.

This is the first step of our routing demo. Click the button below to start the tour.

// In your steps.tsx file
{
  tour: 'next-js-routing-demo',
  steps: [
    {
      icon: <>👋</>,
      title: 'Routing Demo',
      content: <>This is the first step of our routing demo. Click next to navigate to the homepage.</>,
      selector: '#routing-demo-step',
      side: 'bottom',
      showControls: true,
      showSkip: true,
      nextRoute: '/',
    },
    {
      icon: <>❤️</>,
      title: 'Support the Developer',
      content: <>We've navigated to the homepage. Please consider supporting the developer if you find NextStep useful. <br /> <br /> Click next to navigate back to the routing documentation.</>,
      selector: '#buy-me-a-coffee-button',
      side: 'right',
      showControls: true,
      showSkip: true,
      prevRoute: '/docs/nextjs/routing',
      nextRoute: '/docs/nextjs/routing',
    },
    {
      icon: <>🎉</>,
      title: 'Back to Docs',
      content: <>We've navigated back to the routing documentation. You've completed the routing demo!</>,
      selector: '#routing-demo-step',
      side: 'bottom',
      showControls: true,
      showSkip: true,
      prevRoute: '/',
    },
  ],
},

Note: When using nextRoute and prevRoute, NextStep will first navigate to the specified route and then show the next/previous step. NextStep will wait for the page to load and find the element before showing the next step. Ensure that the element is present on the page before using nextRoute or prevRoute. Otherwise, NextStep will route but will not move to the next step until the element is found.