Onboarding · Open source
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
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 composer require amjadiqbal/laravel-driver-js
- 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.
More Laravel packages
All packages
Laravel Sonner
Sonner toast notifications for Laravel, sent from PHP and shown without React.
Laravel Ninja Keys
A Cmd+K / Ctrl+K command palette for Laravel, with the actions defined in PHP.
Laravel SweetAlert2
SweetAlert2 popups, toasts and confirm dialogs from Laravel controllers, Livewire and Alpine.
Laravel Grid.js
Turn any Eloquent query into a searchable, sortable, paginated Grid.js data table with one fluent PHP call.
Laralink
Work on a Composer package inside the Laravel app that uses it, then switch back to the Packagist release.
Refresher
A drop-in replacement for Laravel's RefreshDatabase that restores a cached snapshot of your test database instead of running migrate:fresh.
Kiln
Artisan commands and an optional signed HTTP route to clear, warm and inspect OPcache when you deploy.
Laravel Media Viewer
Show private PDFs, video and audio from any Laravel disk without making the files public.
Laravel Swiper
Swiper sliders, carousels and image galleries for Laravel as Blade components.
Laravel MySQL Advisor
Read-only health checks for the MySQL or MariaDB database behind your Laravel app, with the SQL and the Laravel migration to fix a problem wherever a fix applies.
Laravel Webhook Console
A dashboard and replay tool for the webhooks spatie/laravel-webhook-client stores in your Laravel app.