Back to Course |
Livewire 3 From Scratch: Practical Course

Full-page Components to Replace Laravel Controllers

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

The choice is yours, it's a personal preference. In this lesson, let's see how to do it with full-page components.


Routes

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

use App\Livewire\CreatePost;
 
Route::get('/posts/create', CreatePost::class);

Layout Files

Livewire uses Blade component as an application layout. So it needs to have a {{ $slot }} placeholder. By default, Livewire uses the resources/views/components/layouts/app.blade.php Blade file for the main layout.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
 
<title>{{ $title ?? 'Page Title' }}</title>
</head>
<body>
{{ $slot }}
</body>
</html>

The main layout's location can be changed in two ways: global 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.

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

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

#[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 Title

Setting a unique title for the page is very useful. First, you need to have a $title variable in the layouts title section.

<head>
<title>{{ $title ?? 'Page Title' }}</title>
</head>

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

use Livewire\Attributes\Title;
use Livewire\Component;
 
class CreatePost extends Component
{
// ...
 
#[Title('Create Post')]
public function render()
{
return view('livewire.create-post');
}
}

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

class CreatePost extends Component
{
// ...
 
public function render()
{
return view('livewire.create-post')
->title('Create Post');
}
}

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