Jetstream & Breeze
If you have a project with Jetstream/Breeze the maryUI installer adds a global prefix x-mary-
on maryUI components to avoid naming collision.
You are ready to go, just add maryUI components to your project.
Trade-off
Remember that starter kits add a dozen files that you probably will not use. You have to tweak and maintain them by yourself, because they are copied into your project.
On the other hand you can think it is a waste of time to build everything from the ground. But at least later you will have minimal code to maintain.
- Stater kit: works out of the box, but adds extra code to maintain.
- From the ground: needs extra time to setup, but adds minimal code.
Let's see how easy it is to implement exactly the features we need from the ground in no time, without starter kits.
- Layout
- Components
- Authentication
- Register
Layout
There's not much to say here. As you can see on this Bootcamp, maryUI ships with a default layout. You can look for another layout alternative in the docs, but this is very personal.
Components
The maryUI components provide a great DX and you don't have to worry about maintaining the components by yourself.
Breeze
<div> <x-input-label for="name" :value="__('Name')" /> <x-text-input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" /> <x-input-error :messages="$errors->get('name')" class="mt-2" /></div>
Jetstream
<div> <x-label for="name" value="{{ __('Name') }}" /> <x-input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" /></div>
maryUI
<x-mary-input label="Name" wire:model="name" />
Authentication
Here is what routes/web.php
looks like with Authentication.
- Login route.
- Logout route.
- Protect some routes.
Go ahead and copy/paste this.
use Illuminate\Support\Facades\Route;use Livewire\Volt\Volt; // Users will be redirected to this route if not logged inVolt::route('/login', 'login')->name('login'); // Define the logoutRoute::get('/logout', function () { auth()->logout(); request()->session()->invalidate(); request()->session()->regenerateToken(); return redirect('/');}); // Protected routes hereRoute::middleware('auth')->group(function () { Volt::route('/', 'index'); Volt::route('/users', 'users.index'); Volt::route('/users/create', 'users.create'); Volt::route('/users/{user}/edit', 'users.edit'); // ... more});
Create an empty layout at resources/views/components/layouts/empty.blade.php
to use it as our login page.
<!DOCTYPE html><html lang="{{ str_replace('_', '-', app()->getLocale()) }}"><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover"> <meta name="csrf-token" content="{{ csrf_token() }}"> @vite(['resources/css/app.css', 'resources/js/app.js'])</head><body class="min-h-screen font-sans antialiased bg-base-200/50 dark:bg-base-200"> {{-- You could elaborate the layout here --}} {{-- The important part is to have a different layout from the main app layout --}} <x-main full-width> <x-slot:content> {{ $slot }} </x-slot:content> </x-main></body></html>
And here is the login component.
php artisan make:volt login --class
use Livewire\Attributes\Layout;use Livewire\Attributes\Rule;use Livewire\Attributes\Title;use Livewire\Volt\Component; new#[Layout('components.layouts.empty')] // <-- Here is the `empty` layout#[Title('Login')]class extends Component { #[Rule('required|email')] public string $email = ''; #[Rule('required')] public string $password = ''; public function mount() { // It is logged in if (auth()->user()) { return redirect('/'); } } public function login() { $credentials = $this->validate(); if (auth()->attempt($credentials)) { request()->session()->regenerate(); return redirect()->intended('/'); } $this->addError('email', 'The provided credentials do not match our records.'); }}
<div class="md:w-96 mx-auto mt-20"> <div class="mb-10">Cool image here</div> <x-form wire:submit="login"> <x-input label="E-mail" wire:model="email" icon="o-envelope" inline /> <x-input label="Password" wire:model="password" type="password" icon="o-key" inline /> <x-slot:actions> <x-button label="Create an account" class="btn-ghost" link="/register" /> <x-button label="Login" type="submit" icon="o-paper-airplane" class="btn-primary" spinner="login" /> </x-slot:actions> </x-form></div>
That is it!
Try to navigate to a protected route, and you will be redirected to the login page. The default app layout shipped with maryUI shows the authenticated user and logout button for you.
Register
Add this public extra route to web.php
.
use Livewire\Volt\Volt; Volt::route('/register', 'register');
Create the registration form.
php artisan make:volt register --class
use App\Models\User;use Livewire\Attributes\Layout;use Livewire\Attributes\Rule;use Livewire\Attributes\Title;use Livewire\Volt\Component;use Illuminate\Support\Facades\Hash; new#[Layout('components.layouts.empty')] // <-- The same `empty` layout#[Title('Login')]class extends Component { #[Rule('required')] public string $name = ''; #[Rule('required|email|unique:users')] public string $email = ''; #[Rule('required|confirmed')] public string $password = ''; #[Rule('required')] public string $password_confirmation = ''; public function mount() { // It is logged in if (auth()->user()) { return redirect('/'); } } public function register() { $data = $this->validate(); $data['avatar'] = '/empty-user.jpg'; $data['password'] = Hash::make($data['password']); $user = User::create($data); auth()->login($user); request()->session()->regenerate(); return redirect('/'); }}
<div class="md:w-96 mx-auto mt-20"> <div class="mb-10">Cool image here</div> <x-form wire:submit="register"> <x-input label="Name" wire:model="name" icon="o-user" inline /> <x-input label="E-mail" wire:model="email" icon="o-envelope" inline /> <x-input label="Password" wire:model="password" type="password" icon="o-key" inline /> <x-input label="Confirm Password" wire:model="password_confirmation" type="password" icon="o-key" inline /> <x-slot:actions> <x-button label="Already registered?" class="btn-ghost" link="/login" /> <x-button label="Register" type="submit" icon="o-paper-airplane" class="btn-primary" spinner="register" /> </x-slot:actions> </x-form></div>
It is done!
Hit the /register route on browser and create an account.