jeremykenedy / laravel-darkmode-toggle
A standalone dark mode toggle component for Laravel with multi-framework support (Tailwind, Bootstrap 5, Bootstrap 4) and multiple frontend options (Blade, Livewire, Vue, React, Svelte).
Package info
github.com/jeremykenedy/laravel-darkmode-toggle
Language:Blade
Type:package
pkg:composer/jeremykenedy/laravel-darkmode-toggle
Requires
- php: ^8.2
- illuminate/support: ^12.0|^13.0
This package is auto-updated.
Last update: 2026-03-28 21:20:13 UTC
README
A standalone, framework-agnostic dark mode toggle component for Laravel. Supports Tailwind CSS, Bootstrap 5, and Bootstrap 4, with Blade, Livewire, Vue, React, and Svelte frontend options.
Table of Contents
- Features
- Installation
- Quick Start
- Usage
- Configuration
- Server-Side Persistence
- CSS Framework Switching
- How It Works
- Requirements
- License
Features
- Three modes: Light, Dark, System (follows OS preference)
- Persists to
localStorage(instant, no flash) - Optional server-side persistence (saves to user profile)
- Class-based dark mode (
<html class="dark">) - FOUC prevention via init script
- Multi-framework CSS: Tailwind, Bootstrap 5, Bootstrap 4
- Multi-framework frontend: Blade/Alpine.js, Livewire 3, Vue 3, React 18, Svelte 4
- Configurable via
config/darkmode.php - Artisan install command with framework selection
Installation
composer require jeremykenedy/laravel-darkmode-toggle
Quick Start
php artisan darkmode:install --css=tailwind --frontend=blade
Options
| Flag | Values | Default |
|---|---|---|
--css |
tailwind, bootstrap5, bootstrap4 |
tailwind |
--frontend |
blade, livewire, vue, react, svelte |
blade |
--no-config |
Skip publishing config | - |
Usage
1. Add the init script to <head>
This prevents a flash of the wrong theme on page load:
<head> @include('darkmode::init-script') </head>
2. Add the toggle component
Blade (with Alpine.js):
<x-darkmode-toggle />
Livewire:
<livewire:darkmode-toggle />
Vue:
<script setup> import DarkmodeToggle from './vendor/darkmode-toggle/DarkmodeToggle.vue' </script> <template> <DarkmodeToggle persist-url="/darkmode/preference" /> </template>
React:
import DarkmodeToggle from './vendor/darkmode-toggle/DarkmodeToggle' export default function Nav() { return <DarkmodeToggle persistUrl="/darkmode/preference" /> }
Svelte:
<script> import DarkmodeToggle from './vendor/darkmode-toggle/DarkmodeToggle.svelte' </script> <DarkmodeToggle persistUrl="/darkmode/preference" />
3. Publish frontend components (Vue/React/Svelte only)
php artisan darkmode:install --frontend=vue php artisan darkmode:install --frontend=react php artisan darkmode:install --frontend=svelte
Configuration
php artisan vendor:publish --tag=darkmode-config
Key options in config/darkmode.php:
return [ 'strategy' => 'class', // Dark mode strategy 'class_name' => 'dark', // Class added to <html> 'default' => 'system', // Default mode 'storage_key' => 'theme', // localStorage key 'persist_to_server' => true, // Save to DB when authenticated 'persist_route' => '/profile/dark-mode', 'persist_method' => 'PUT', 'persist_field' => 'dark_mode', 'css_framework' => null, // null = inherit from ui-kit config 'routes' => [ 'enabled' => true, 'prefix' => 'darkmode', 'middleware' => ['web', 'auth'], ], ];
Server-Side Persistence
The package includes a route PUT /darkmode/preference that saves the preference. To use your own route (e.g., from laravel-profiles), set in config:
'persist_route' => '/profile/dark-mode', 'routes' => ['enabled' => false], // disable package route
The toggle sends a JSON request:
{ "dark_mode": "dark" }
CSS Framework Switching
Switch CSS framework at any time:
# In .env
UI_KIT_CSS=bootstrap5
Or set directly in config/darkmode.php:
'css_framework' => 'bootstrap5',
The component automatically renders with the correct framework's classes.
How It Works
- Init script runs synchronously in
<head>, readslocalStorage, addsdarkclass before paint - Toggle component renders sun/moon/monitor icons, dropdown with Light/Dark/System options
- On selection: updates
localStorage, toggles HTML class, optionally PUTs to server - System mode: listens for
prefers-color-schememedia query changes in real time
Requirements
- PHP 8.2+
- Laravel 12 or 13
- Alpine.js 3 (for Blade views)
License
MIT