Skip to content

Onboarding · Open source

Laravel Driver.js

Build Driver.js product tours in PHP and render them with one Blade component.

Laravel 12 and 13 PHP 8.3+ v1.0.0 Free · MIT
Laravel Driver.js: Build Driver.js product tours in PHP and render them with one Blade component.

What it solves

Adding Driver.js to a Laravel app usually means hand-writing a script for each page, remembering who has already seen the tour, and wiring it to Livewire yourself.

You define tours and steps in PHP, put <x-driver-js> in the view, and start a tour from a button, Alpine, Livewire or JavaScript. once() shows a tour only the first time a visitor sees it, with no JavaScript to write and no npm build step.

  • Tours and steps built in PHP with Driver.js's own option names
  • Invalid sides, alignments, buttons and hook names rejected before they reach the browser
  • once() auto-starts a tour only the first time a visitor sees it
  • Start a tour from a button, Alpine, a Livewire component or JavaScript
  • Tour text escaped with Js::from(), and Driver.js loaded from a pinned CDN URL with SRI hashes
  • Scripts carry Laravel's CSP nonce, and Driver.js can be bundled with Vite instead
A Laravel billing dashboard dimmed behind a Driver.js tour on step 3 of 4: a popover titled Overdue invoices, with Back and Next buttons, points at the highlighted Overdue invoices card.
A Laravel billing dashboard dimmed behind a Driver.js tour on step 3 of 4: a popover titled Overdue invoices, with Back and Next buttons, points at the highlighted Overdue invoices card.

Install

Requires PHP 8.3+ and Laravel 12 and 13.

composer require amjadiqbal/laravel-driver-js

Usage

use AmjadIqbal\DriverJS\Facades\Driver;

// In a controller: a welcome tour that new users see once
$tour = Driver::tour('welcome')
    ->once('welcome-v1')
    ->step(null, 'Welcome to Acme', 'A 30-second tour of where everything lives.')
    ->step('#revenue', 'Monthly revenue', 'Updated every hour.', ['side' => 'bottom']);

return view('dashboard', ['tour' => $tour]);

// In the view: <x-driver-js :tour="$tour" />

Setup

The service provider and the Driver facade are registered automatically. Publishing the config is only needed to change the defaults.

  1. 1 composer require amjadiqbal/laravel-driver-js
  2. 2 php artisan vendor:publish --tag=driver-js-config

A tour in Blade

Pass a tour built in PHP with <x-driver-js :tour="$tour" />, or write the Driver.js steps in the view. The first <x-driver-js> on a page prints the Driver.js stylesheet, script and a small runtime. Add @driverJsAssets to your <head> to print them there instead.

<x-driver-js name="settings" :steps="[
    ['element' => '#profile', 'popover' => ['title' => 'Your profile', 'description' => 'Name, photo and email.']],
    ['element' => '#billing', 'popover' => ['title' => 'Billing', 'description' => 'Plans and invoices.', 'side' => 'left']],
]" :config="['showProgress' => false]" />

Building tours

once() auto-starts a tour the first time a visitor sees it; change the key to show a new version. manual() never auto-starts and waits for a trigger. highlight() shows one element instead of a tour.

Driver::tour('welcome')
    ->once('welcome-v1')
    ->step('#search', 'Search', 'Find any customer.', ['side' => 'bottom', 'align' => 'start'])
    ->step(null, 'All set', 'A step with no element shows a centred popover.')
    ->showProgress(true, '{{current}} of {{total}}')
    ->buttonLabels(next: 'Next', previous: 'Back', done: 'Got it');

Starting a tour

Use a button, an Alpine event, or the StartsTours trait in a Livewire component. The tour must be on the page.

<button data-driver-start="welcome">Take the tour</button>

<button x-data @click="$dispatch('driver-js:start', { tour: 'export-hint' })">What's new?</button>

// Livewire, with use AmjadIqbal\DriverJS\Livewire\StartsTours;
$this->startTour('after-save');

Assets and security

  • Tour text is escaped with Js::from().
  • Driver.js 1.10.2 loads from a pinned jsDelivr URL with Subresource Integrity hashes.
  • The scripts carry Laravel's CSP nonce when you use one.
  • To bundle Driver.js with Vite, set 'cdn' => false in config/driver-js.php and import it in resources/js/app.js.
  • Publish the view with php artisan vendor:publish --tag=driver-js-views to change the markup.

Hire me

Need this built into your app, or something custom?

I wrote Laravel Driver.js. I can wire it into your Laravel app, extend it for your case, or build the feature around it. Tell me what you need and you'll get a plan and a quote, free.

Support

Found a bug or want a feature? Open an issue on GitHub. For help adding it to your own project, use the quote form above.

Need something built?

Free quote in 60 seconds