Learn how to add dark mode to your Laravel app with our step-by-step guide.
Some themes may have a readymade dark mode, while others require manual implementation.
We have created an easy-to-follow step-by-step guide for implementing dark mode in your app. While adding dark mode is simple, ensuring that the dark mode persists even when the user navigates to a new page or reload can be challenging.
To solve this issue, we use persistent cookies to store the user’s preferred theme, allowing the app to maintain the user’s selected mode.
Table of Contents
Step-1: navigate to the directory
Open a terminal or command prompt and navigate to the directory where you want to create your new Laravel app.
Step-2: create a new Laravel app
Run the following command to create a new Laravel app
composer create-project --prefer-dist laravel/laravel projectname
Step-3:project directory
Navigate to the your project directory.
cd projectname
Step-4: start a server in Laravel
Now run the following command to start a development server
php artisan serve
Step-5: Local address
You can either click on a URL or manually paste it into your browser’s address bar.
In Laravel, to implement dark mode functionality, it’s recommended to create a new view and controller specifically for the dark mode feature, rather than modifying the default view. However, it’s also possible to use the same controller for both views. Additionally, creating a main layout for the entire application can help streamline the implementation process.
Step-6: Create a new controller in Laravel
php artisan make:controller darkThemeControllers
Step-7: Create a layouts directory and create file
Right-click on the views folder and Create a new folder called “Layouts” and then proceed to create a blade file, such as “app.blade.php”, inside it.
In Laravel, layouts/app.blade.php is a template file that serves as the main layout for the entire application. It contains the basic HTML structure of the page, including the head and body tags, as well as any common elements that appear on multiple pages, such as navigation menus or headers and footers. we will add dark mode in app.blade.php file.
This makes it easier to maintain consistency in the design of your application and reduces the amount of repetitive code that you have to write.
In Laravel, you can define different sections in your layout file using the @yield directive.
These sections can then be filled with content by child views that extend the layout file.
app.blade.php file
<!DOCTYPE html>
<html>
<head>
<title>@yield('title')</title>
<link rel="stylesheet" href="{{ asset('darkmode.css') }}">
</head>
<body>
@yield('content')
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="theme-switch">
<label class="form-check-label" for="theme-switch">Dark mode</label>
</div>
<script src="{{ asset('darkmode.js') }}"></script>
</body>
</html>
This is a basic HTML layout for a web page that uses a master layout file called “app.blade.php” in Laravel framework. The layout defines the basic structure of the page and includes a link to a CSS file for styling and a script file for functionality.
The @yield(‘title’) and @yield(‘content’) are Blade directives that define sections in the layout file that can be replaced by the content of the child view file that extends the layout.
The asset() function is a Laravel helper function that generates a URL for a given file in the public directory of your application. It allows you to reference CSS, JS, and image files in your HTML code without having to hardcode the full URL. In this case, it is used to link to the “darkmode.css” and “darkmode.js” files.
Step-8: Defined routes in Laravel
Go to web.php and create three routes
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\darkThemeControllers;
Route::get('/',[darkThemeControllers::class,'index'])->name('/');
Route::get('/first', [darkThemeControllers::class, 'first'])->name('first');
Route::get('/second', [darkThemeControllers::class, 'second'])->name('second');
It is also necessary to include controllers in the web.php file.
use App\Http\Controllers\darkThemeControllers;
‘/’: This route is mapped to the index method of the darkThemeControllers class. It is assigned the name ‘/’, which means it can be referred to by name using route(‘/’).
‘/first’: This route is mapped to the first method of the darkThemeControllers class. It is assigned the name ‘first’, which means it can be referred to by name using route(‘first’).
‘/second’: This route is mapped to the second method of the darkThemeControllers class. It is assigned the name ‘second’, which means it can be referred to by name using route(‘second’).
Step-9: go to the controller
Now go to the darkThemeControllers created earlier and add below code.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class darkThemeControllers extends Controller
{
//
public function index(){
return view('index');
}
public function first(){
return view('first');
}
public function second(){
return view('second');
}
}
The code above defines a controller class called “darkThemeControllers” that includes three methods: “index()”, “first()”, and “second()”. Each method returns a corresponding view: “index”, “first”, and “second”. In order to ensure that the dark mode feature works across all pages, we need to create three separate view files: “index”, “first”, and “second”. By checking these three files, we can verify that the dark mode feature remains functional even when switching between pages.
Step-10: Create view file
Right-click on the views folder and Create a new file called index.blade.php
@extends('layouts.app')
@section('title', 'Home')
@section('content')
<h1 style="text-align:center">This is first home</h1></br >
<a href="{{route('/')}}">Home page</a></br >
<a href="{{route('first')}}">first page</a></br >
<a href="{{route('second')}}">second page</a>
@endsection
We extends the layouts.app layout and defines a title for the page as “Home” using the @section directive.
The @section(‘content’) directive defines the main content of the page, which in this case includes an H1 header and three links to other pages.
he links use the route() function to generate URLs based on the names of the routes defined in web.php. For example, route(‘first’) generates a URL for the first route, which is defined as [darkThemeControllers::class, ‘first’] in web.php.
The @endsection directive ends the content section.
Step-11 first and second view page.
To follow the same approach, you can create the first and second view pages after creating the index view page.
Step-12: create a JavaScript file
Let’s create a JavaScript file.
To do so, right-click on the “public” directory and select “New File”. Name the file “darkmode.js” and add the following JavaScript code.
const themeSwitch = document.getElementById('theme-switch');
themeSwitch.addEventListener('change', function() {
if (this.checked) {
// Set dark mode
document.body.classList.add('dark-mode');
localStorage.setItem('theme', 'dark');
document.cookie = "theme=dark;expires=Thu, 01 Jan 2099 00:00:00 UTC;path=/";
} else {
// Set light mode
document.body.classList.remove('dark-mode');
localStorage.setItem('theme', 'light');
document.cookie = "theme=light;expires=Thu, 01 Jan 2099 00:00:00 UTC;path=/";
}
});
// Apply theme preference on page load
if (localStorage.getItem('theme') === 'dark') {
// Set dark mode
document.body.classList.add('dark-mode');
themeSwitch.checked = true;
} else {
// Set light mode
document.body.classList.remove('dark-mode');
themeSwitch.checked = false;
}
// Check if cookie exists and set the theme accordingly
if (getCookie("theme")) {
if (getCookie("theme") === 'dark') {
document.body.classList.add('dark-mode');
themeSwitch.checked = true;
} else {
document.body.classList.remove('dark-mode');
themeSwitch.checked = false;
}
}
// Helper function to get cookie value by name
function getCookie(name) {
const value = "; " + document.cookie;
const parts = value.split("; " + name + "=");
if (parts.length === 2) return parts.pop().split(";").shift();
}
when the user toggles the switch, it checks if the switch is in the checked state, and if so, adds a dark-mode class to the body element, sets a local storage item with the key theme to the value ‘dark’, and sets a cookie with the same key and value with an expiration date far in the future.
If the switch is not checked, the code removes the dark-mode class from the body, sets the local storage item with the key theme to the value ‘light’, and sets a cookie with the same key and value with the same expiration date.
The code then checks if a local storage item with the key theme exists, and if so, sets the dark mode based on its value. Finally, there is a helper function getCookie that takes a cookie name and returns its value.
Step-13: create a CSS style file
We are now incorporating CSS code to implement dark mode and light mode styles.
Let’s create a css file.
To do so, right-click on the “public” directory and select “New File”. Name the file “darkmode.css” and add the following css code.
body {
/* Light mode styles */
background-color: #f9fafb;
color: #333;
}
.dark-mode {
/* Dark mode styles */
background-color: #1e1e1e;
color: #fff;
}
/* Style the toggle switch */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
Great news! We have successfully created a Dark Mode theme in Laravel.