You're browsing the documentation for Livewire v4 beta. Go to stable v3 docs →

Components

Are you a visual learner?
Master Livewire with our in-depth screencasts
Watch now

Livewire components are essentially PHP classes with properties and methods that can be called directly from a Blade template. This powerful combination allows you to create full-stack interactive interfaces with a fraction of the effort and complexity of modern JavaScript alternatives.

This guide covers everything you need to know about creating, rendering, and organizing Livewire components. You'll learn about the different component formats available (single-file, multi-file, and class-based), how to pass data between components, and how to use components as full pages.

Creating components

You can create a component using the make:livewire Artisan command:

php artisan make:livewire post.create

This creates a single-file component at:

resources/views/components/post/⚡create.blade.php

<?php
 
use Livewire\Component;
 
new class extends Component {
public $title = '';
 
public function save()
{
// Save logic here...
}
};
?>
 
<div>
<input wire:model="title" type="text">
<button wire:click="save">Save Post</button>
</div>
Why the ⚡ emoji?

You might be wondering about the lightning bolt in the filename. This small touch serves a practical purpose: it makes Livewire components instantly recognizable in your editor's file tree and search results. Since it's a Unicode character, it works seamlessly across all platforms — Windows, macOS, Linux, Git, and your production servers.

The emoji is completely optional and if you find it outside your comfort zone you can disable it entirely in your config/livewire.php file:

'make_command' => [
'emoji' => false,
],

Creating page components

When creating components that will be used as full pages, use the pages:: namespace to organize them in a dedicated directory:

php artisan make:livewire pages::post.create

This creates the component at resources/views/pages/post/⚡create.blade.php. This organization makes it clear which components are pages versus reusable UI components.

Learn more about using components as pages in the Page components section below. You can also register your own custom namespaces—see the Component namespaces documentation.

Multi-file components

As your component or project grows, you might find the single-file approach limiting. Livewire offers a multi-file alternative that splits your component into separate files for better organization and IDE support.

To create a multi-file component, pass the --mfc flag:

php artisan make:livewire post.create --mfc

This creates a directory with all related files together:

resources/views/components/post/⚡create/
├── create.php # PHP class
├── create.blade.php # Blade template
├── create.js # JavaScript (optional, with --js flag)
└── create.test.php # Pest test (optional, with --test flag)

Converting between formats

Livewire provides the livewire:convert command to seamlessly convert components between single-file and multi-file formats.

Auto-detect and convert:

php artisan livewire:convert post.create
# Single-file → Multi-file (or vice versa)

Explicitly convert to multi-file:

php artisan livewire:convert post.create --mfc

This will parse your single-file component, create a directory structure, split the files, and delete the original.

Explicitly convert to single-file:

php artisan livewire:convert post.create --sfc

This combines all files back into a single file and deletes the directory.

Test files are deleted when converting to single-file

If your multi-file component has a test file, you'll be prompted to confirm before conversion since test files cannot be preserved in the single-file format.

When to use each format

Single-file components (default):

  • Best for most components
  • Keeps related code together
  • Easy to understand at a glance
  • Perfect for small to medium components

Multi-file components:

  • Better for large, complex components
  • Improved IDE support and navigation
  • Clearer separation when components have significant JavaScript

Class-based components:

  • Familiar to developers from Livewire v2/v3
  • Traditional Laravel separation of concerns
  • Better for teams with established conventions
  • See Class-based components below

Rendering components

You can include a Livewire component within any Blade template using the <livewire:component-name /> syntax:

<livewire:component-name />

If the component is located in a sub-directory, you can indicate this using the dot (.) character:

resources/views/components/post/⚡create.blade.php

<livewire:post.create />

For namespaced components—like pages::—use the namespace prefix:

<livewire:pages::post.create />

Passing props

To pass data into a Livewire component, you can use prop attributes on the component tag:

<livewire:post.create title="Initial Title" />

For dynamic values or variables, prefix the attribute with a colon:

<livewire:post.create :title="$initialTitle" />

Data passed into components is received through the mount() method:

<?php
 
use Livewire\Component;
 
new class extends Component {
public $title;
 
public function mount($title = null)
{
$this->title = $title;
}
 
// ...
};

You can think of the mount() method as a class constructor. It runs when the component initializes, but not on subsequent requests within a page's session. You can learn more about mount() and other helpful lifecycle hooks within the lifecycle documentation.

To reduce boilerplate code, you can omit the mount() method and Livewire will automatically set any properties with names matching the passed values:

<?php
 
use Livewire\Component;
 
new class extends Component {
public $title; // Automatically set from prop
 
// ...
};
These properties are not reactive by default

The $title property will not update automatically if the outer :title="$initialValue" changes after the initial page load. This is a common point of confusion when using Livewire, especially for developers who have used JavaScript frameworks like Vue or React and assume these parameters behave like "reactive props" in those frameworks. But, don't worry, Livewire allows you to opt-in to making your props reactive.

Passing route parameters as props

When using components as pages, you can pass route parameters directly to your component. The route parameters are automatically passed to the mount() method:

Route::livewire('/posts/{id}', 'pages::post.show');
<?php // resources/views/pages/post/⚡show.blade.php
 
use Livewire\Component;
 
new class extends Component {
public $postId;
 
public function mount($id)
{
$this->postId = $id;
}
};

Livewire also supports Laravel's route model binding:

Route::livewire('/posts/{post}', 'pages::post.show');
<?php // resources/views/pages/post/⚡show.blade.php
 
use App\Models\Post;
use Livewire\Component;
 
new class extends Component {
public Post $post; // Automatically bound from route
 
// No mount() needed - Livewire handles it automatically
};

Page components

Components can be routed to directly as full pages using Route::livewire(). This is one of Livewire's most powerful features, allowing you to build entire pages without traditional controllers.

Route::livewire('/posts/create', 'pages::post.create');

When a user visits /posts/create, Livewire will render the pages::post.create component inside your application's layout file.

Page components work just like regular components, but they're rendered as full pages with access to:

  • Custom layouts
  • Page titles
  • Route parameters and model binding
  • Named slots for layouts

For complete information about page components, including layouts, titles, and advanced routing, see the Pages documentation.

Accessing data in views

Livewire provides several ways to pass data to your component's Blade view. Each approach has different performance and security characteristics.

Component properties

The simplest approach is using public properties, which are automatically available in your Blade template:

<?php
 
use Livewire\Component;
 
new class extends Component {
public $title = 'My Post';
};
<div>
<h1>{{ $title }}</h1>
</div>

Protected properties must be accessed with $this->:

public $title = 'My Post'; // Available as {{ $title }}
protected $apiKey = 'secret-key'; // Available as {{ $this->apiKey }}
Protected properties are not sent to the client

Unlike public properties, protected properties are never sent to the frontend and cannot be manipulated by users. This makes them safe for sensitive data. However, they are not persisted between requests, which limits their usefulness in most Livewire scenarios. They're best used for static values defined in the property declaration that you don't want exposed client-side.

For complete information about properties, including persistence behavior and advanced features, see the properties documentation.

Computed properties

Computed properties are methods that act like memoized properties. They're perfect for expensive operations like database queries:

use Livewire\Attributes\Computed;
 
#[Computed]
public function posts()
{
return Post::with('author')->latest()->get();
}
<div>
@foreach ($this->posts as $post)
<article wire:key="{{ $post->id }}">{{ $post->title }}</article>
@endforeach
</div>

Notice the $this-> prefix - this tells Livewire to call the method and cache the result for the current request only (not between requests). For more details, see the computed properties section in the properties documentation.

Passing data from render()

Similar to a controller, you can pass data directly to the view using the render() method:

public function render()
{
return $this->view([
'author' => Auth::user(),
'currentTime' => now(),
]);
}

Keep in mind that render() runs on every component update, so avoid expensive operations here unless you need fresh data on every update.

Organizing components

While Livewire automatically discovers components in the default resources/views/components/ directory, you can customize where Livewire looks for components and organize them using namespaces.

Component namespaces

Component namespaces allow you to organize components into dedicated directories with a clean reference syntax.

By default, Livewire provides two namespaces:

  • pages:: — Points to resources/views/pages/
  • layouts:: — Points to resources/views/layouts/

You can define additional namespaces in your config/livewire.php file:

'component_namespaces' => [
'layouts' => resource_path('views/layouts'),
'pages' => resource_path('views/pages'),
'admin' => resource_path('views/admin'), // Custom namespace
'widgets' => resource_path('views/widgets'), // Another custom namespace
],

Then use them when creating, rendering, and routing:

php artisan make:livewire admin::users-table
<livewire:admin::users-table />
Route::livewire('/admin/users', 'admin::users-table');

Additional component locations

If you want Livewire to discover components in additional directories beyond the defaults, you can configure them in your config/livewire.php file:

'component_paths' => [
resource_path('views/components'),
resource_path('views/admin/components'),
resource_path('views/widgets'),
],

Now Livewire will automatically discover components in all these directories.

Programmatic registration

For more dynamic scenarios (like package development or runtime configuration), you can register components, locations, and namespaces programmatically in a service provider:

Register an individual component:

use Livewire\Livewire;
 
// In a service provider's boot() method (e.g., App\Providers\AppServiceProvider)
Livewire::addComponent(
name: 'custom-button',
viewPath: resource_path('views/ui/button.blade.php')
);

Register a component directory:

Livewire::addLocation(
viewPath: resource_path('views/admin/components')
);

Register a namespace:

Livewire::addNamespace(
namespace: 'ui',
viewPath: resource_path('views/ui')
);

This approach is useful when you need to register components conditionally or when building Laravel packages that provide Livewire components.

Registering class-based components

For class-based components, use the same methods but with the class parameter instead of path:

use Livewire\Livewire;
 
// In a service provider's boot() method (e.g., App\Providers\AppServiceProvider)
 
// Register an individual class-based component
Livewire::addComponent(
name: 'todos',
\App\Livewire\Todos::class
);
 
// Register a location for class-based components
Livewire::addLocation(
classNamespace: 'App\\Admin\\Livewire'
);
 
// Create a namespace for class-based components
Livewire::addNamespace(
namespace: 'admin',
classNamespace: 'App\\Admin\\Livewire',
classPath: app_path('Admin/Livewire'),
classViewPath: resource_path('views/admin/livewire')
);

Class-based components

For teams migrating from Livewire v3 or those who prefer a more traditional Laravel structure, Livewire fully supports class-based components. This approach separates the PHP class and Blade view into different files in their conventional locations.

Creating class-based components

php artisan make:livewire CreatePost --class

This creates two separate files:

app/Livewire/CreatePost.php

<?php
 
namespace App\Livewire;
 
use Livewire\Component;
 
class CreatePost extends Component
{
public function render()
{
return view('livewire.create-post');
}
}

resources/views/livewire/create-post.blade.php

<div>
{{-- ... --}}
</div>

When to use class-based components

Use class-based components when:

  • Migrating from Livewire v2/v3
  • Your team prefers a more traditional file structure
  • You have established conventions around class-based architecture

Use single-file or multi-file components when:

  • Starting a new Livewire v4 project
  • You want better component colocation
  • You want to use the latest Livewire conventions

Configuring default component type

If you want class-based components by default, configure it in config/livewire.php:

'make_command' => [
'type' => 'class',
],

Customizing component stubs

You can customize the files (or stubs) Livewire uses to generate new components by running:

php artisan livewire:stubs

This creates stub files in your application that you can modify:

Single-file component stubs:

  • stubs/livewire-sfc.stub — Single-file components

Multi-file component stubs:

  • stubs/livewire-mfc-class.stub — PHP class for multi-file components
  • stubs/livewire-mfc-view.stub — Blade view for multi-file components
  • stubs/livewire-mfc-js.stub — JavaScript for multi-file components
  • stubs/livewire-mfc-test.stub — Pest test for multi-file components

Class-based component stubs:

  • stubs/livewire.stub — PHP class for class-based components
  • stubs/livewire.view.stub — Blade view for class-based components

Additional stubs:

  • stubs/livewire.attribute.stub — Attribute classes
  • stubs/livewire.form.stub — Form classes

Once published, Livewire will automatically use your custom stubs when generating new components.

Troubleshooting

Component not found

Symptom: Error message like "Component [post.create] not found" or "Unable to find component"

Solutions:

  • Verify the component file exists at the expected path
  • Check that the component name in your view matches the file structure (dots for subdirectories)
  • For namespaced components, ensure the namespace is defined in config/livewire.php or manually registered in a service provider
  • Try clearing your view cache: php artisan view:clear

Component shows blank or doesn't render

Common causes:

  • Missing root element in your Blade template (Livewire requires exactly one root element)
  • Syntax errors in the PHP section of your component
  • Check your Laravel logs for detailed error messages

Class name conflicts

Symptom: Errors about duplicate class names when using single-file components

Solution: This can happen if you have multiple single-file components with the same name in different directories. Either:

  • Rename one of the components to be unique
  • Namespace one of the directories for more clear separation

See also

  • Properties — Manage component state and data
  • Actions — Handle user interactions with methods
  • Pages — Use components as full pages with routing
  • Nesting — Compose components together and pass data between them
  • Lifecycle Hooks — Execute code at specific points in a component's lifecycle