Install in a Fresh Laravel App
composer require laravel-frontend-presets/tall
php artisan preset:install tall
Run this immediately after composer create-project laravel/laravel to avoid conflicts.
First Use Case: Basic Blade + Livewire Page
php artisan make:livewire Welcome
resources/views/welcome.blade.php to extend the default layout:
<x-app-layout>
<livewire:welcome />
</x-app-layout>
npm run dev
Key Files to Inspect First
resources/views/layouts/app.blade.php (default layout)resources/js/app.js (Vite entry point)tailwind.config.js (Tailwind customization)vite.config.js (Asset pipeline config)Livewire Components
// app/Http/Livewire/ExampleComponent.php
public function render()
{
return view('livewire.example-component', [
'data' => $this->fetchData(),
]);
}
<!-- resources/views/livewire/example-component.blade.php -->
<div x-data="{ open: false }">
<button @click="open = !open">Toggle</button>
<!-- Alpine.js interactivity -->
</div>
Reusable Layout Sections
Use @stack/@push for dynamic content:
<!-- layouts/app.blade.php -->
<body>
@include('layouts.partials.head')
<div class="container">
@yield('content')
@stack('scripts')
</div>
</body>
Vite Integration
// resources/js/app.js
import './bootstrap';
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();
<!-- layouts/app.blade.php -->
@vite(['resources/js/app.js', 'resources/css/app.css'])
Tailwind Customization
Extend tailwind.config.js:
module.exports = {
theme: {
extend: {
colors: {
primary: '#3b82f6',
},
},
},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
],
};
Use the built-in Tailwind pagination views:
{{ $posts->links('pagination::tailwind') }}
For custom auth, extend resources/views/auth/ templates while leveraging:
<x-guest-layout>
<!-- Custom auth logic -->
</x-guest-layout>
Service Providers: Register Alpine/Livewire in AppServiceProvider:
public function boot()
{
Livewire::component('welcome', \App\Http\Livewire\Welcome::class);
}
Middleware: Use app.blade.php to inject auth checks:
@auth
<x-nav-link href="/dashboard">Dashboard</x-nav-link>
@endauth
vite.config.js and app.js.public function test_component_renders()
{
$this->livewire(Welcome::class)
->assertSee('Welcome');
}
@testing directive:
<div x-data @testing>
<!-- Testable Alpine logic -->
</div>
Vite Hot Module Replacement (HMR)
resources/js/app.js imports are not properly configured.app.js.Tailwind JIT Mode
tailwind.config.js has mode: 'jit' and proper content paths:
content: [
'./resources/**/*.blade.php',
'./resources/**/*.js',
],
Livewire + Alpine Conflicts
x-data may interfere with Livewire’s reactivity.wire:ignore on Alpine-managed elements:
<div wire:ignore x-data="{ /* ... */ }">
<!-- Alpine-only logic -->
</div>
Asset Compilation
npm run build fails due to missing dependencies.npm install and ensure node_modules is in .gitignore.Layout Inheritance
app.blade.php may break if @stack/@yield are misused.@extends('layouts.app') at the top of child views.Tailwind Classes Not Applying
tailwind.config.js for correct content paths.npx tailwindcss -i ./resources/css/app.css -o ./resources/css/dist/app.css --watch to debug.Livewire Component Not Updating
AppServiceProvider.Alpine.js Not Working
app.js initializes Alpine:
document.addEventListener('alpine:init', () => {
Alpine.store('auth', {
user: @json(auth()->user()),
});
});
Custom Directives
Extend Alpine in app.js:
Alpine.directive('focus', (el) => el.focus());
Tailwind Plugins
Add to tailwind.config.js:
plugins: [
require('tailwindcss-animate'),
],
Livewire View Composition
Override default Livewire views in resources/views/livewire/:
<!-- resources/views/livewire/authentication.blade.php -->
<x-guest-layout>
{{ $slot }}
</x-guest-layout>
Vite Aliases
Configure vite.config.js for path aliases:
resolve: {
alias: {
'@': path.resolve(__dirname, './resources/js'),
},
},
Dark Mode
Enable in tailwind.config.js:
darkMode: 'class',
Component Boilerplate
Use php artisan make:livewire --view to scaffold components with pre-linked views.
Shared Alpine Stores
Centralize state in app.js:
Alpine.store('app', {
init() {
this.notifications = [];
},
addNotification(message) {
this.notifications.push(message);
},
});
Tailwind Variants Extend variants for dynamic styling:
theme: {
extend: {
variants: {
opacity: ['responsive', 'hover', 'focus', 'group-hover'],
},
},
},
Livewire + File Uploads
Use livewire:model with Alpine for drag-and-drop:
<input
type="file"
wire:model="image"
x-on:change="previewImage($event)"
>
<img x-show="preview" x-bind:src="preview" class="mt-4">
How can I help you explore Laravel packages today?