Download
Please note that the sample project does not include the Metronic Tailwind CSS source files by default. To integrate the styles, you need to copy the Metronic Tailwind CSS source files from your downloaded Metronic folder.
Clone Integration Repository
git clone https://github.com/keenthemes/metronic-tailwind-html-integration.git
cd metronic-tailwind-html-integration/metronic-tailwind-laravel
Copy Assets Folder
assets
folder from the
metronic-tailwind-html/dist
directory into your Laravel project
public/
directory. The resulting directory structure should look like this:
public/assets/
.
Install Dependencies
# Install PHP dependencies
composer install
# Install Node.js dependencies
npm install
# Build assets for development
npm run dev
Environment Configuration
# Copy environment file
cp .env.example .env
# Generate application key
php artisan key:generate
# Configure database in .env file
# DB_CONNECTION=mysql
# DB_DATABASE=your_database_name
# Run database migrations
php artisan migrate
Start Development Server
# Start the Laravel development server
php artisan serve
# In another terminal, start Vite for asset watching
npm run dev
http://127.0.0.1:8000
to see your Laravel app in action. You can explore all 10 demo layouts:
# Demo Layouts Available
http://127.0.0.1:8000/demo1/ # Sidebar Layout
http://127.0.0.1:8000/demo2/ # Header Layout
http://127.0.0.1:8000/demo3/ # Minimal Layout
http://127.0.0.1:8000/demo4/ # Creative Layout
http://127.0.0.1:8000/demo5/ # Modern Layout
http://127.0.0.1:8000/demo6/ # Professional Layout
http://127.0.0.1:8000/demo7/ # Corporate Layout
http://127.0.0.1:8000/demo8/ # Executive Layout
http://127.0.0.1:8000/demo9/ # Premium Layout
http://127.0.0.1:8000/demo10/ # Ultimate Layout
If you prefer to create a project from scratch, follow the manual setup steps in the next section.
Create Laravel Project
This guide assumes you have PHP 8.2+ and Composer installed. For a ready-to-use Laravel project, you can download our pre-configured example from the Download section.
Prerequisites & Environment Setup
# Check requirements
php --version # Should be 8.2+
composer --version
node --version # For Vite asset building
# Create new Laravel project
composer create-project laravel/laravel my-metronic-app
cd my-metronic-app
# Or using Laravel installer
laravel new my-metronic-app
cd my-metronic-app
Install Additional Dependencies
# Install Node.js dependencies for Vite
npm install
Configure Project Structure
# Create directory structure for Metronic integration
mkdir -p resources/views/layouts/{demo1,demo2,demo3,demo4,demo5,demo6,demo7,demo8,demo9,demo10}
mkdir -p resources/views/pages/{demo1,demo2,demo3,demo4,demo5,demo6,demo7,demo8,demo9,demo10}
mkdir -p resources/views/components/{demo1,demo2,demo3,demo4,demo5,demo6,demo7,demo8,demo9,demo10,shared}
mkdir -p app/Http/Controllers
mkdir -p public/assets
# Create placeholder for assets (will be copied later)
touch public/assets/.gitkeep
Environment Configuration
# Copy and configure environment
cp .env.example .env
php artisan key:generate
# Configure database (edit .env file)
# DB_CONNECTION=mysql
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=my_metronic_app
# DB_USERNAME=root
# DB_PASSWORD=
# Create database and run migrations
php artisan migrate
Configure Vite for Asset Building
// vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js'
],
refresh: true,
}),
],
build: {
rollupOptions: {
external: [
// Exclude Metronic assets from Vite bundling
/^/assets/.*/
]
}
}
});
Test Project Setup
# Start development servers
php artisan serve &
npm run dev &
# Test the application
curl -I http://127.0.0.1:8000
# You should see HTTP/1.1 200 OK
# Visit http://127.0.0.1:8000 in your browser
For Laravel-specific documentation and advanced configuration, refer to the official Laravel documentation .
Integrate Core
This section assumes you have completed the "Create Laravel Project" steps. We'll be creating Laravel controllers and routes focused on demonstrating Metronic layouts.
Create Demo Controllers
# Create controllers for all demos
php artisan make:controller Demo1Controller
php artisan make:controller Demo2Controller
php artisan make:controller Demo3Controller
php artisan make:controller Demo4Controller
php artisan make:controller Demo5Controller
php artisan make:controller Demo6Controller
php artisan make:controller Demo7Controller
php artisan make:controller Demo8Controller
php artisan make:controller Demo9Controller
php artisan make:controller Demo10Controller
<?php
// app/Http/Controllers/Demo1Controller.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class Demo1Controller extends Controller
{
public function index()
{
return view('pages.demo1.index', [
'pageTitle' =>
'Demo 1 - Sidebar Layout',
'pageDescription' => 'Central Hub for Personal Customization',
'currentDemo' => 'demo1',
]);
}
}
Configure Routes
routes/web.php
to include all demo routes:
<?php
// routes/web.php
use App\Http\Controllers\{
Demo1Controller, Demo2Controller, Demo3Controller, Demo4Controller, Demo5Controller,
Demo6Controller, Demo7Controller, Demo8Controller, Demo9Controller, Demo10Controller
};
use Illuminate\Support\Facades\Route;
// Redirect root to demo1
Route::get('/', function () {
return redirect('/demo1');
});
// Demo routes
Route::get('/demo1', [Demo1Controller::class, 'index'])->
name('demo1.index');
Route::get('/demo2', [Demo2Controller::class, 'index'])->name('demo2.index');
Route::get('/demo3', [Demo3Controller::class, 'index'])->name('demo3.index');
Route::get('/demo4', [Demo4Controller::class, 'index'])->name('demo4.index');
Route::get('/demo5', [Demo5Controller::class, 'index'])->name('demo5.index');
Route::get('/demo6', [Demo6Controller::class, 'index'])->name('demo6.index');
Route::get('/demo7', [Demo7Controller::class, 'index'])->name('demo7.index');
Route::get('/demo8', [Demo8Controller::class, 'index'])->name('demo8.index');
Route::get('/demo9', [Demo9Controller::class, 'index'])->name('demo9.index');
Route::get('/demo10', [Demo10Controller::class, 'index'])->name('demo10.index');
Create Blade Components
# Create shared components
php artisan make:component Shared/ThemeMode
php artisan make:component Shared/SearchBox
php artisan make:component Shared/NotificationDropdown
# Create demo-specific components
php artisan make:component Demo1/NavigationMenu
php artisan make:component Demo1/SidebarToggle
php artisan make:component Demo1/UserDropdown
php artisan make:component Demo2/NavigationMenu
php artisan make:component Demo2/BalanceWidget
php artisan make:component Demo2/UserDropdown
# Create components for other demos following the same pattern
<?php
// app/View/Components/Demo1/NavigationMenu.php
namespace App\View\Components\Demo1;
use Illuminate\View\Component;
class NavigationMenu extends Component
{
public $activeRoute;
public function __construct($activeRoute = null)
{
$this->
activeRoute = $activeRoute ?? request()->route()->getName();
}
public function render()
{
return view('components.demo1.navigation-menu');
}
}
Create Base Layout Templates
# Create base layout files for each demo
touch resources/views/layouts/demo1/base.blade.php
touch resources/views/layouts/demo2/base.blade.php
touch resources/views/layouts/demo3/base.blade.php
touch resources/views/layouts/demo4/base.blade.php
touch resources/views/layouts/demo5/base.blade.php
touch resources/views/layouts/demo6/base.blade.php
touch resources/views/layouts/demo7/base.blade.php
touch resources/views/layouts/demo8/base.blade.php
touch resources/views/layouts/demo9/base.blade.php
touch resources/views/layouts/demo10/base.blade.php
# Create page templates
touch resources/views/pages/demo1/index.blade.php
touch resources/views/pages/demo2/index.blade.php
# ... continue for all demos
Create Temporary Templates
{{-- resources/views/pages/demo1/index.blade.php --}}
<!DOCTYPE html>
<html>
<head>
<title>
{{ $pageTitle }}
</title>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
</head>
<body>
<h1>
{{ $pageTitle }}
</h1>
<p>
{{ $pageDescription }}
</p>
<p>
Demo layout placeholder - will be replaced with Metronic templates in the next section.
</p>
<p>
<a href="{{ route('demo2.index') }}">
Go to Demo 2
</a>
</p>
</body>
</html>
Test Core Integration
# Start the development server
php artisan serve
# Test the routes
curl -I http://127.0.0.1:8000/demo1
curl -I http://127.0.0.1:8000/demo2
# Check route list
php artisan route:list --name=demo
For complete controller examples and implementation details, refer to the actual project files in the downloaded integration package:
metronic-tailwind-laravel/app/Http/Controllers/
.
Integrate Styles
This section assumes you have completed the "Create Laravel Project" and "Integrate Core" steps. Make sure you have the Metronic HTML files available for copying assets and templates.
Copy Metronic Assets
# Navigate to your Laravel project root
cd my-metronic-app
# Copy assets from Metronic HTML package
# Replace /path/to/metronic-tailwind-html with your actual path
cp -r /path/to/metronic-tailwind-html/dist/assets public/
# Verify the assets are copied
ls -la public/assets/
# You should see directories like:
# css/, js/, media/, vendors/, etc.
public/assets/
directory contains:
public/assets/
├── css/
│ └── styles.css
├── js/
│ ├── core.bundle.js
│ └── layouts/
│ ├── demo1.js
│ ├── demo2.js
│ └── ... (demo3-demo10.js)
├── media/
│ ├── app/
│ ├── avatars/
│ ├── logos/
│ └── images/
└── vendors/
├── apexcharts/
├── keenicons/
└── ktui/
Create Base Template Partials
resources/views/layouts/partials/head.blade.php
:
<title>
{{ $pageTitle ?? 'Dashboard' }} | Metronic
</title>
<meta charset="utf-8"/>
<meta content="follow, index" name="robots"/>
<link href="{{ url(request()->path()) }}" rel="canonical"/>
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport"/>
<meta content="{{ $pageDescription ?? 'Metronic admin dashboard' }}" name="description"/>
<!--begin::Fonts-->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"/>
<!--end::Fonts-->
<!--begin::Vendor Stylesheets-->
@stack('vendor_css')
<!--end::Vendor Stylesheets-->
<!--begin::Global Stylesheets Bundle-->
<link href="{{ asset('assets/vendors/apexcharts/apexcharts.css') }}" rel="stylesheet"/>
<link href="{{ asset('assets/vendors/keenicons/styles.bundle.css') }}" rel="stylesheet"/>
<link href="{{ asset('assets/css/styles.css') }}" rel="stylesheet"/>
<!--end::Global Stylesheets Bundle-->
<!--begin::Custom Stylesheets-->
@stack('custom_css')
<!--end::Custom Stylesheets-->
resources/views/layouts/partials/scripts.blade.php
:
<!--begin::Javascript-->
<!--begin::Global Javascript Bundle-->
<script src="{{ asset('assets/js/core.bundle.js') }}">
</script>
<script src="{{ asset('assets/vendors/ktui/ktui.min.js') }}">
</script>
<script src="{{ asset('assets/vendors/apexcharts/apexcharts.min.js') }}">
</script>
<!--end::Global Javascript Bundle-->
<!--begin::Custom Javascript-->
@stack('custom_js')
<!--end::Custom Javascript-->
<!--begin::Page Vendors Javascript-->
@stack('vendor_js')
<!--end::Page Vendors Javascript-->
<!--begin::Page Custom Javascript-->
@stack('page_js')
<!--end::Page Custom Javascript-->
<!--begin::Compiled App Scripts-->
@vite(['resources/js/app.js'])
<!--end::Compiled App Scripts-->
<!--end::Javascript-->
Convert Metronic HTML to Blade Templates
metronic-tailwind-html/dist/demo1/index.html
(and demo2-demo10)
• Create
resources/views/layouts/demo1/base.blade.php
using the main layout structure
• Extract headers, sidebars, and footers into partials
• Create
resources/views/pages/demo1/index.blade.php
with dashboard content
• Replace static paths with Laravel asset helpers
• Add Blade template blocks and directives
{{-- resources/views/layouts/demo1/base.blade.php --}}
<!DOCTYPE html>
<html class="h-full" data-kt-theme="true" data-kt-theme-mode="light" dir="ltr" lang="en">
<head>
@include('layouts.partials.head')
@stack('demo1_css')
</head>
<body class="antialiased flex h-full text-base text-foreground bg-background demo1 kt-sidebar-fixed kt-header-fixed">
<!--begin::Theme mode setup-->
<script>
var defaultThemeMode = "light";
var themeMode;
if (document.documentElement) {
if (document.documentElement.hasAttribute("data-kt-theme-mode")) {
themeMode = document.documentElement.getAttribute("data-kt-theme-mode");
} else {
if (localStorage.getItem("data-kt-theme") !== null) {
themeMode = localStorage.getItem("data-kt-theme");
} else {
themeMode = defaultThemeMode;
}
}
if (themeMode === "system") {
themeMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
document.documentElement.setAttribute("data-kt-theme", themeMode);
}
</script>
<!--end::Theme mode setup-->
<!--begin::Page layout-->
<div class="flex grow">
@include('layouts.demo1.partials.sidebar')
<div class="wrapper flex grow flex-col">
@include('layouts.demo1.partials.header')
<main class="grow content pt-5" id="content" role="content">
@yield('content')
</main>
@include('layouts.demo1.partials.footer')
</div>
</div>
<!--end::Page layout-->
@include('layouts.partials.scripts')
<script src="{{ asset('assets/js/layouts/demo1.js') }}">
</script>
@stack('demo1_js')
</body>
</html>
Key Blade Template Conversions
{{-- 1. Template inheritance and sections --}}
@extends('layouts.demo1.base')
@section('content')
<!-- Your page content here -->
@endsection
{{-- 2. Convert static asset paths --}}
{{-- FROM: src="assets/media/logos/logo.svg" --}}
{{-- TO: --}}
<img alt="Logo" src="{{ asset('assets/media/logos/logo.svg') }}"/>
{{-- 3. Use Blade directives for dynamic content --}}
{{-- FROM:
<h1>
Dashboard
</h1>
--}}
{{-- TO: --}}
<h1>
{{ $pageTitle ?? 'Dashboard' }}
</h1>
{{-- 4. Include Blade components --}}
<x-demo1.navigation-menu :active="$currentRoute">
</x-demo1.navigation-menu>
<x-shared.theme-mode>
</x-shared.theme-mode>
{{-- 5. Add CSS/JS stacks for page-specific assets --}}
@push('custom_css')
<style>
/* Page-specific styles */
</style>
@endpush
@push('page_js')
<script>
// Page-specific JavaScript
</script>
@endpush
Configure Asset Management
# Update your .gitignore to exclude copied assets
echo "/public/assets" >> .gitignore
# Test asset loading
php artisan serve
npm run dev
# Verify assets are accessible:
# http://127.0.0.1:8000/assets/css/styles.css
# http://127.0.0.1:8000/assets/js/core.bundle.js
# http://127.0.0.1:8000/assets/media/logos/logo.svg
resources/css/app.css
to complement Metronic styles:
/* resources/css/app.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Custom styles that complement Metronic */
.custom-integration {
/* Your custom styles here */
}
/* Override Metronic styles if needed */
.kt-custom-override {
/* Careful overrides */
}
Test Complete Integration
# Start both development servers
php artisan serve &
npm run dev &
# Test all demo layouts:
curl -I http://127.0.0.1:8000/demo1 # Sidebar layout
curl -I http://127.0.0.1:8000/demo2 # Header layout
curl -I http://127.0.0.1:8000/demo3 # Minimal layout
curl -I http://127.0.0.1:8000/demo4 # Creative layout
curl -I http://127.0.0.1:8000/demo5 # Modern layout
curl -I http://127.0.0.1:8000/demo6 # Professional layout
curl -I http://127.0.0.1:8000/demo7 # Corporate layout
curl -I http://127.0.0.1:8000/demo8 # Executive layout
curl -I http://127.0.0.1:8000/demo9 # Premium layout
curl -I http://127.0.0.1:8000/demo10 # Ultimate layout
# Check browser console for JavaScript errors
# Verify all CSS and JS files are loading correctly
Performance Optimization (Optional)
# Build assets for production
npm run build
# Optimize Laravel for production
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Optimize Composer autoloader
composer install --optimize-autoloader --no-dev
# Test production build
php artisan serve --env=production
Congratulations! You have successfully integrated Metronic Tailwind CSS with Laravel. Your application now features 10 beautiful demo layouts with full Laravel functionality.