Courses

Livewire 3 for Beginners with Laravel 12 Starter Kit

Full-Page Components and Layouts

Summary of this lesson:
- Creating full-page Livewire components instead of Laravel controllers
- Setting up routes to point directly to Livewire components
- Configuring layouts and dynamic page titles for Livewire components
- Removing duplicate code by using shared layouts

In general, there are two main ways to use Livewire:

  • You build the full project with Laravel Controllers and use Livewire only for small dynamic elements on the pages
  • You use Livewire Components instead of Laravel Controllers, with so-called Full-Page Components

Your choice is yours; it's a personal preference. In this lesson, we'll see how to do it with Full-Page components.


Routes

Instead of mapping to the Controller in the Routes files, you need to map directly to the Livewire component.

routes/web.php:

use App\Livewire\CompanyCreate;
use App\Livewire\CompanyEdit;
 
// ...
 
Route::resource('companies', CompanyController::class);
 
Route::get('companies/create', CompanyCreate::class)
->name('companies.create');
Route::get('companies/{company}/edit', CompanyEdit::class)
->name('companies.edit');

Layout Files

Both Create and Edit forms can use the same layout for the HTML header and footer.

Livewire uses Blade components as an application layout. It must have a {{ $slot }} placeholder.

By default, Livewire uses the resources/views/components/layouts/app.blade.php Blade file for the main layout. So, we take the main HTML from our companies/create.blade.php and companies/edit.blade.php and put in that new layout file with a {{ $slot }} placeholder.

resources/views/components/layouts/app.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Form</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="flex items-center justify-center min-h-screen bg-gray-100">
{{ $slot }}
</body>
</html>

Then, we may delete three files:

  • resources/views/companies/create.blade.php
  • resources/views/companies/edit.blade.php
  • app/Http/Controllers/CompanyController.php

Visually, nothing changes in the forms. But now our routes lead directly to the Livewire components with their Blade + layout files, without Laravel Controller/Blade files.

We also avoided code duplication, reusing the same layout for both pages.


Configure Layout File Location

As mentioned, Livewire uses the resources/views/components/layouts/app.blade.php Blade file for the main layout.

Its location can be changed in two ways: globally and per-component.

Global Layout Configuration

To use the same layout for all components, you can set layout in the config/livewire.php to the path where your layout is.

config/livewire.php:

// ...
 
'layout' => 'layouts.app',
 
// ...

Per-component Layout Configuration

To set the layout for a particular component, you must use the #[Layout] attribute either above the render() method or the class declaration.

app/Livewire/CompanyCreate.php:

use Livewire\Attributes\Layout;
use Livewire\Component;
 
#[Layout('layouts.app')]
class CompanyCreate extends Component
{
// ...
 
#[Layout('layouts.app')]
public function render()
{
return view('livewire.company-create');
}
}

Or you can have a base Livewire component to set the layout. For example, the layout could be different for the admin. Then, you would set the layout in one "global parent" Livewire component.

#[Layout('components.layouts.admin)]
class AdminComponent extends \Livewire\Component {}

And all other Livewire components should then extend this AdminComponent instead of a \Livewire\Component.

class AdminPanel extends AdminComponent {}

Setting Page Head Meta Title

Currently, our main layout has a static title of "Simple Form":

resources/views/components/layouts/app.blade.php:

<head>
<title>Simple Form</title>

How can you make it dynamic and different for Create/Edit forms?

First, you need to have a $title variable in the layouts title section.

resources/views/components/layouts/app.blade.php:

<head>
<title>{{ $title ?? 'Simple Form' }}</title>
</head>

Next, similar to setting the layout per component using attributes, you can set the title by adding the #[Title] attribute.

app/Livewire/CompanyCreate.php:

use Livewire\Attributes\Title;
use Livewire\Component;
 
#[Title('Create Company')]
class CompanyCreate extends Component
{
// ...
}

This is the visual result:

If you need a dynamic title, use the title() method in the component's render() method.

app/Livewire/CompanyEdit.php:

class CompanyEdit extends Component
{
public function render()
{
return view('livewire.company-edit')
->title('Edit Company ' . $this->name);
}
}

This is the result:

And that's it: you don't need Laravel Controllers, so all your Routes may lead to full-page Livewire components.

Here's the GitHub commit for this lesson. It's the final commit for this country/city demo project. In the following few lessons, I'll just show code snippets without the full repository, and then we'll move to try out Livewire Starter Kit in Laravel 12, which will have its own separate GitHub repository.

Previous: Edit Form: Pass Parameters to Component

No comments yet…

avatar
You can use Markdown