Skip to content

Tour Completion Tracking

One of the most powerful features of Laravel Driver.js is automatic tour completion tracking. When a user completes a tour, the package remembers this so the tour is not shown again on subsequent visits.

How It Works

When you create a named tour using DriverJs::tour('name'), the package wraps the tour's onDestroyed behavior to send an AJAX request to your Laravel backend when the tour is completed. If you have also defined a custom onDestroyed callback, it will still run after the completion request is queued. The backend then stores the completion status using the configured storage driver.

Checking Tour Completion

Using the Facade

php
use RealRashid\LaravelDriverJs\Facades\DriverJs;

// Check if a specific tour has been completed
if (! DriverJs::tourCompleted('onboarding')) {
    // Show the tour
}

Using the Instance Method

php
$driver = driverjs('onboarding');

if ($driver->isCompleted()) {
    // Tour already completed
}

Marking a Tour as Completed

php
DriverJs::tour('onboarding')->markCompleted();

This is typically done automatically when the tour is destroyed, but you can also call it manually if needed.

Resetting Tour Completion

php
DriverJs::tour('onboarding')->resetCompletion();

This removes the completion record, allowing the tour to be shown again on the next page load.

Using the @driverjsTour Blade Directive

The easiest way to render a tour only if it hasn't been completed:

blade
@driverjsTour('onboarding')

This directive:

  1. Checks if the 'onboarding' tour has been completed
  2. If completed, outputs nothing
  3. If not completed, creates and renders the tour

You'll need to define the tour steps in a service provider or a view composer before the directive is evaluated.

Conditional Tour Rendering in Controllers

php
use RealRashid\LaravelDriverJs\Facades\DriverJs;

public function dashboard()
{
    $tourHtml = '';

    if (! DriverJs::tourCompleted('onboarding')) {
        $tourHtml = DriverJs::tour('onboarding')
            ->showProgress()
            ->step('#header', 'Welcome!', 'This is the dashboard.')
            ->step('#nav', 'Navigation', 'Navigate your app.')
            ->render();
    }

    return view('dashboard', compact('tourHtml'));
}

Then in your Blade template:

blade
{!! $tourHtml !!}

The AJAX Completion Endpoint

Laravel Driver.js automatically registers a POST route at /driverjs/tour/completed that handles tour completion tracking. This route accepts a JSON payload with a tour field and marks the tour as completed using the configured storage driver.

The route is protected by Laravel's CSRF token, which is automatically included in the AJAX request by the package's JavaScript code.

Security note: By default this endpoint has no authentication middleware. When using the database storage driver, add the auth middleware via the route_middleware option in config/driverjs.php to ensure only authenticated users can record completions:

php
'route_middleware' => ['web', 'auth'],

Disabling Tour Tracking

If you don't need tour tracking for a particular instance, simply don't call tour() — use addStep() and render() directly instead:

php
// No tour name = no completion tracking
DriverJs::addStep('#header')
    ->title('Welcome')
    ->description('The header');

DriverJs::addStep('#nav')
    ->title('Navigation');

DriverJs::render();

That's it! You're now equipped to track tour completions using Laravel Driver.js.