Build a Blog with Laravel Livewire
Time to read: 8 minutes
When Laravel started out, it was primarily targeted at backend developers, while frontend developers used other tools/frameworks like React, Angular, etc..
Why was this? Laravel didn’t support essentials like DOM manipulation, dynamic interfacing, etc. These concepts could only be utilised outside of Laravel, making Livewire a game changer.
In this article, we will dive into several Livewire concepts, and consider how these concepts enable easy integration between the backend and rendering feedback on the frontend using Livewire. Then, we'll build a Livewire application, so that you get hands-on experience with them.
Prerequisites
To follow along with this tutorial, you will need the following:
PHP 8.3
Composer installed globally
Prior experience with PHP
Prior experience with Laravel
Some command-line experience would be ideal, though not required
What is Laravel Livewire?
Livewire is a framework built for Laravel that fuses the backend with the frontend. It allows the manipulation of the DOM, dynamic interfaces, and how requests are handled between the controllers and views.
Furthermore, this is all handled within Laravel, and integrates perfectly with JavaScript tools like Alpine.js, CSS frameworks like Tailwind CSS, and local plugins like Laravel Echo.
Typically, a new development project will use separate tools and frameworks for building the backend and frontend. Livewire, however, incorporates both aspects into the same monolithic Laravel application. This enables easier application development.
Some good Livewire use cases
For validation
In programming, validation is essential to building an application. Livewire keeps that going by simplifying tasks such as form validation, and input type/data validation, etc, as in the examples below.
In a Livewire resource file, for example: resources/views/livewire/blogs.php, the below code demonstrates how Livewire uses the `wire:model` method to bind the value of the input property.
Then, similarly in a Livewire component file, e.g., app/Livewire/blogs.php, the title
value is passed into the $rules
protected array for validation. Following Laravel’s native validation, the function won’t continue to execute if the validate()
method fails.
For more validation control on the front end, submitting can be prevented using the wire:submit.prevent
method if the required validation options are not met. For example, if a required field like title
is left empty.
For handling errors
Errors from form validation can be logged directly to the frontend using the @error
method. The @error
tag takes the model like title
and returns the validation message; for example:
It's component-based
Livewire makes the interaction between Laravel Blade templates and their corresponding components alongside other Laravel internal methods seamless. Usually, you’d install JQuery and Alpine.js to initiate browser events like onClick
in a Blade template.
With Livewire, events that directly update the component can be triggered using methods like wire:click
. The process then requests server-side code as an AJAX request and returns them to the template without reloading.
To demonstrate, below, a button created in resources/views/livewire/counter.php utilises the wire:click
to increment a count every time it is clicked.
Its corresponding component app/Livewire/Counter.php, contains the increment()
function that increments the $count
variable by one, every time it is initiated.
If you’re a fan of Alpine.js, the behaviour change of $count
can also be displayed in markup:
The $wire()
method is an Alpine.js component embedded into the Livewire template. So, it can be called and used to interact with component public variables and functions alike.
The $wire()
method goes beyond just interacting with functions and variables, to initiating functions that expect parameters and act as requests. Check out the documentation for more.
For state tracking
State change comes in handy when real-time tracking of changes is important. An example of this could be displaying more content based on a click()
method, for example:
Build an example Livewire application
In this section, we will build a small blog application using Livewire, and, within it, cover further important concepts like validation, state change, and rendering components.
To start, we need to create a new Laravel project. We will call the project: laravel_livewire.
Next, install the Livewire package using the below command.
Then, open the project in your text editor or IDE of choice. Add the Livewire style and script to resources/views/welcome.blade.php, by adding @livewireStyles
just before </head>
and @livewireScripts
just before </body>
, as depicted in the example below.
Create the blog controller
Next, we have to create our Livewire Blogs controller, by running the following command in the project's top-level directory.
This will create two files, a controller file in app/Livewire/Blogs.php and a Livewire view file in resources/views/livewire/blogs.blade.php.
Now, in the welcome.blade.php file, include the new Livewire views by updating the body
tag to match the following.
Insert blog data
To store the blog data, we will first generate a migration file to create a blog table. To do that, run the following commands in the terminal.
These will create a new migration file for a "blogs" table, and create a Laravel model to interact with the table, when the migration command is run later in this article.
Next, run the commands below to generate a factory which will be used to insert a couple of records to display in our Livewire view later in the article, and a seeder to seed fake records in the "blogs" table.
Then, edit the "blogs" table's migration (it's the file ending with blogs_table.php in the database/migrations directory) to include the required columns, by updating the up()
function to match the code below.
These changes need to be reflected in the database model class. So, in app/Models/Blog.php add a primary key and fillable parameters for the "blogs" table, by updating the file to match the code below.
Then, (if required) update the database variables in .env to use SQLite as the database backend.
After that, run the migration using the command below.
Next, update the definition()
function, in database/factories/BlogFactory.php, to match the code below, so that it generates random fake records to fill the "blogs" table.
Then, in the seeder file, database/seeders/BlogSeeder.php, seed 10 records with the BlogFactory
by updating the run()
function to match the implementation below.
Then in database\seeders\DatabaseSeeder.php, update the run()
function to include the blogs table seeder.
With this all in place, run the Artisan console's seed command to add the information to the database.
Show blog entries
Earlier in this article, we included the Livewire blog template in resources/views/welcome.blade.php using the <livewire:blogs />
tag.
In this section, we will fetch all the entries from the "blogs" table to give an example of how Livewire filters data and displays records, and also what our blog will look like with data.
To do that, in app/Livewire/Blogs.php update the render()
function to include the code below.
The code above performs a simple fetch using Laravel pagination in the Livewire component. I have also taken the liberty of adding a call to count()
to track the count of the blog entries retrieved.
Then, update the template in resources/views/livewire/blogs.blade.php to loop through the retrieved blog entries using the @foreach
tag, and add blogs->links()
to display pagination templates for the blogs.
Templating in Livewire uses syntax from Laravel and hence uses the @foreach
array method to filter and recognize Laravel pagination methods; an example being {!! $blogs→link() !!}
.
Add search
Naturally, a blog would incorporate a search option to fetch similar results to the search query. With methods like wire:mode.live
, search queries are sent in real-time and responses are automatically injected into the template.
To do that, in our resources/views/livewire/blogs.php template, add our search tags by adding the code below just below the <h1>
tag.
The search tag uses the wire:model.live
method to listen and send live updates to the component model search
. So, every time text is input, the "blogs" table is searched, filtered by the input text, and the records returned update the blogs template.
Next, update the Blogs
component, app/Livewire/Blogs.php, to handle search, by updating it to match the code below.
In the component above:
A public
$search
variable has been addedA protected
$queryString
command has been added to keep the query parameter active even after refreshThe
render()
function's been updated to use thesearch
macro to filter the blogs title column records using the value ofsearch
In the render()
function, Blog::search()
search is a macro written into the Laravel application. Add it in app/Providers/AppServiceProvider.php by updating the boot()
method to match the definition below.
Here’s what it looks like.
Create a blog post
Now, let’s create a new blog post to understand, more insightfully, how Livewire handles validation and requests.
Create a new Livewire component and template with the following commands.
Then, include some HTML in the newly created resources/views/livewire/create.blade.php template file.
Then in the resources/views/livewire/blogs.blade.php update the create blog button to open the canvas.
The template input for the
title
anddescription
fields also includes@error
tags. This will log a validation error message to the off-canvas Livewire component.In the form tag, the Livewire
wire:submit.prevent="create"
method is set in the form to prevent submission if all the required parameters are not met. For example, if the user initiates the submission without filling out thedescription
field.
Next, update the app/Livewire/Create.php component to include validation and create a new blog.
In the above code, we added validation to check the $rules
, just like is used in Laravel.
Additions
Remember how our blog entries have likes and dislikes. We will make them interactive by tracking clicks and updating their count. To do that, update the like
and dislike
tags in the blog template (resources/views/livewire/blogs.blade.php) to include the code below.
Then, in app/Livewire/Blogs.php, include the functions to update the count for both likes and dislikes on a single blog, by adding the like()
and dislike()
functions below.
After fetching the blog from the given $id
, the functions will update the like count, and then return the blog. This will automatically update the blog in Livewire.
Now, go ahead and launch your application by running the following command.
Testing
Now that the application has been set, we can run a test to create a new blog, search for a blog, and drop a like or dislike reaction to the blog.
Create Blog
To create, go to http://localhost:8000 on the web browser and click on the “create blog” button, like in the example below, to open the Create Blog canvas.
Add a title and description to the new blog post and click “post”. The newly created blog will be rendered on the resources/views/livewire/blogs.blade.php file. Also, notice in the next image that the blog count also increments to track the addition.
Search Blog
Next, search for a random title, in this case, the search will be “content”. It’ll filter the database for related blog titles that contain “content” as a word and render that result to the page.
React to blog
Next, go ahead and click on a reaction for a random blog.
Conclusion
In this article, we reviewed Livewire and its fundamentals, such as rendering components, change in state, validation, etc., and several use cases. We also implemented a blog website to explain the different concepts Livewire offers.
With this in mind, LiveWire will be a great package to adopt when building the next blog with a state change requirement while maintaining safe forms and adding great filtering.
Kenneth Ekandem is a software engineer from Nigeria currently in the blockchain space, but interested in learning everything computer science has to offer. He'd love to go to space one day and own his own vlogging channel to teach the next generation of programmers. You can reach out to him on Twitter, LinkedIn, and GitHub.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.