Building a Multi-Step Form with Laravel, Livewire, and MongoDB

This article was wriiten by Moses Anumadu. In modern-day applications, there is often a need to collect user data through forms. When many details are required from users, the form can be very long and look messy. This often leads to a bad user experience and a high bounce rate from the application. A simple solution to this is creating multi-step forms. This tutorial will build a multi-step form using MongoDB, Laravel, and Laravel Livewire. For this tutorial, we are using MongoDB as our database because it stores data in nested form, document-based model, and has a flexible schema. MongoDB does not need many tables and relationships like a typical relational database would. Also, it does not require creating migrations. If you know nothing about MongoDB, you can read our Getting Started docs for more. Livewire, on the other hand, is a full-stack Laravel framework that enables developers to build dynamic interfaces easily without the need to write extensive JavaScript code. Livewire is easy to use and uses Laravel syntax. Check out the Laravel documentation to get started with Livewire. With that said, let's get started. Prerequisites To follow along with this tutorial, the following are required: Global installation of PHP and Composer MongoDB PHP Driver A free MongoDB Atlas cluster NPM Prior Laravel knowledge Prior Livewire knowledge Familiarity with MongoDB and NoSQL databases Environment setup Before proceeding, ensure that you have the MongoDB PHP Driver installed in the development environment so that MongoDB can work effectively. To verify, run the command below: php -i | grep mongo The expected output should look similar to the image below: If you have a different output, it means you probably do not have the MongoDB PHP Driver installed. To install it, visit the MongoDB extension for detailed instructions on how to install it. Also, ensure that you have PHP and Composer installed before proceeding. Project setup Let's get started building our multi-step form by creating a fresh Laravel project. We can do this using the command below: composer create-project laravel/laravel multi_step_form_tutorial After creating the Laravel project, we need to configure the application to work with MongoDB. Laravel does not come configured to work with MongoDB out of the box. We must install and configure the Laravel-MongoDB package to get it to work. So, let's get started by installing the Laravel-mongodb package using the command below: composer require mongodb/laravel-mongodb After successfully installing the Laravel-MongoDB package, we need to adjust some of the configuration in the config/database.php file to get it to work. You can do that by adding the code below: 'mongodb' => [ 'driver' => 'mongodb', 'dsn' => env('MONGODB_URI'), 'database' => 'YOUR_DATABASE_NAME', ], Let's take a moment to explain. The dsn value is obtained from the .env file. In your .env file, create a value for MONGODB_URI and set it to the value of your MongoDB Atlas connection string, like below: MONGODB_URI="" DB_CONNECTION=mongodb Set up Livewire Let's proceed to install and configure Livewire to work in our application. We first need to install Livewire using the command: composer require livewire/livewire After installing Livewire, we need to import it into the app. To keep things organized, let's create a layout file and make it a Blade component file. If Blade templates sound new to you, check out the Laravel documentation to get started. You can also get a deeper dive into Blade custom directives. With that said, let's generate our Blade template using the artisan command below: php artisan make:component layouts/App This will generate two files: app/View/Components/layouts/App.php and resources/views/components/layouts/app.blade.php. Open resources/views/components/layouts/app.blade.php and replace the content of the page with the code below: Multi-Step Form @vite(['resources/css/app.css', 'resources/js/app.js']) {{-- If using Vite --}} @livewireStyles {{ $slot ?? '' }} @livewireScripts From the code above, we added the HTML layout for the layout file. We also imported Livewire using @livewireStyles and @livewireScripts. This makes Livewire available on any page with this layout. Before we create the Livewire multi-form component, let's ensure that the database configuration works correctly. To do this, we need to create a route in routes/web.php to ping our MongoDB Atlas cluster and ensure things are set up correctly. Navigate to routes/web.php and add the following code snippet below the existing code on the page: use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; Route::get('/ping', function (Request $request) { $connection = DB::connection('mongodb'); try { $connection->command(['ping' => 1]); $msg = 'MongoDB is accessible!'; } catch (Exception $e) { $msg = 'You are

Mar 25, 2025 - 23:10
 0
Building a Multi-Step Form with Laravel, Livewire, and MongoDB

This article was wriiten by Moses Anumadu.

In modern-day applications, there is often a need to collect user data through forms. When many details are required from users, the form can be very long and look messy. This often leads to a bad user experience and a high bounce rate from the application. A simple solution to this is creating multi-step forms.
This tutorial will build a multi-step form using MongoDB, Laravel, and Laravel Livewire.
For this tutorial, we are using MongoDB as our database because it stores data in nested form, document-based model, and has a flexible schema. MongoDB does not need many tables and relationships like a typical relational database would. Also, it does not require creating migrations. If you know nothing about MongoDB, you can read our Getting Started docs for more.

Livewire, on the other hand, is a full-stack Laravel framework that enables developers to build dynamic interfaces easily without the need to write extensive JavaScript code.

Livewire is easy to use and uses Laravel syntax. Check out the Laravel documentation to get started with Livewire.

With that said, let's get started.

Prerequisites

To follow along with this tutorial, the following are required:

Environment setup

Before proceeding, ensure that you have the MongoDB PHP Driver installed in the development environment so that MongoDB can work effectively. To verify, run the command below:

php -i | grep mongo

The expected output should look similar to the image below:

A screen shot of a terminal with the expected output that show a user has MongoDB PHP Driver installed correctly.

If you have a different output, it means you probably do not have the MongoDB PHP Driver installed. To install it, visit the MongoDB extension for detailed instructions on how to install it.

Also, ensure that you have PHP and Composer installed before proceeding.

Project setup

Let's get started building our multi-step form by creating a fresh Laravel project. We can do this using the command below:

composer create-project laravel/laravel multi_step_form_tutorial

After creating the Laravel project, we need to configure the application to work with MongoDB. Laravel does not come configured to work with MongoDB out of the box. We must install and configure the Laravel-MongoDB package to get it to work. So, let's get started by installing the Laravel-mongodb package using the command below:

composer require mongodb/laravel-mongodb

After successfully installing the Laravel-MongoDB package, we need to adjust some of the configuration in the config/database.php file to get it to work. You can do that by adding the code below:

'mongodb' => [
'driver' => 'mongodb',
'dsn' => env('MONGODB_URI'),
'database' => 'YOUR_DATABASE_NAME',
],

Let's take a moment to explain. The dsn value is obtained from the .env file. In your .env file, create a value for MONGODB_URI and set it to the value of your MongoDB Atlas connection string, like below:

MONGODB_URI="<>"
DB_CONNECTION=mongodb

Set up Livewire

Let's proceed to install and configure Livewire to work in our application. We first need to install Livewire using the command:

composer require livewire/livewire

After installing Livewire, we need to import it into the app. To keep things organized, let's create a layout file and make it a Blade component file. If Blade templates sound new to you, check out the Laravel documentation to get started. You can also get a deeper dive into Blade custom directives. With that said, let's generate our Blade template using the artisan command below:

php artisan make:component layouts/App

This will generate two files: app/View/Components/layouts/App.php and resources/views/components/layouts/app.blade.php. Open resources/views/components/layouts/app.blade.php and replace the content of the page with the code below:


 lang="en">

 charset="UTF-8">
 name="viewport" content="width=device-width, initial-scale=1.0">
</span>Multi-Step Form<span class="nt">
@vite(['resources/css/app.css', 'resources/js/app.js']) {{-- If using Vite --}}
@livewireStyles

 class="bg-gray-100">
 class="container mx-auto mt-10">
{{ $slot ?? '' }}
@livewireScripts

From the code above, we added the HTML layout for the layout file. We also imported Livewire using @livewireStyles and @livewireScripts. This makes Livewire available on any page with this layout.
Before we create the Livewire multi-form component, let's ensure that the database configuration works correctly. To do this, we need to create a route in routes/web.php to ping our MongoDB Atlas cluster and ensure things are set up correctly. Navigate to routes/web.php and add the following code snippet below the existing code on the page:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

Route::get('/ping', function (Request $request) {
$connection = DB::connection('mongodb');
try {
$connection->command(['ping' => 1]);
$msg = 'MongoDB is accessible!';
} catch (Exception $e) {
$msg = 'You are not connected to MongoDB. Error: ' . $e->getMessage();
}
return ['msg' => $msg];
});

Now, start the application using:

php artisan serve

This will start the application with the IP address 127.0.0.1:8000. If the 8000 port is not available, Laravel will automatically switch to an available port.
In a different terminal window, run the following to install and build the Node.js dependencies in the application.

Npm install && Npm run dev

Let's test. From your browser, navigate to the newly created route, 127.0.0.1:8000/ping. If everything was done right, your screen should look just like the image below:

Image of a browser tab with a JSON response saying

Building the Livewire component

Before building the Livewire component, let's talk a little about how our form will work. We are building a multi-step form with three (3) steps. The first step will contain the basic user information, like name and email. The second step will contain address details like street, city, or state, and the third will contain pieces of information like checkboxes and dropdowns for gender and marital status.

The form will be programmed to validate data for each step, save the validated data, and have a back, next, and submit button. Information will be saved for each validated step in our database.

MongoDB schema is very flexible and often preferred when handling dynamic data. Its schematic approach to saving data makes it a good approach for our form here. With MongoDB, we can easily add new fields to the form and don’t need to add extra columns to a migration file. Also, when working with MongoDB in Laravel, we don't need to create migration files. New fields can be added on the fly.

With that said, let's create our Livewire component using the command below:

php artisan livewire:make MultiStepForm

After running the command above, it will create a Livewire component with two files: app/Livewire/MultiStepForm.php and resources/views/livewire/multi-step-form.blade.php. app/Livewire/MultiStepForm.php will contain all the PHP code for the component while resources/views/livewire/multi-step-form.blade.php will contain the HTML side of things.

Let's import our Livewire component into our resources/views/welcome.blade.php file by updating the content of the page with the code below:


 />

In routes/web.php, create a route for our Livewire component by adding the code below.

Route::get('/', function () {
    return view('welcome');
});

With that done, replace the content of resources/views/livewire/multi-step-form.blade.php with the code below:

class="max-w-4xl mx-auto p-6 bg-white shadow-xl rounded-xl"> @if (session('success')) class="mb-4 p-4 bg-green-100 text-green-700 rounded-lg"> {{ session('success') }}
@endif class="text-4xl">Multi step form with MongoDB class="text-base font-semibold mb-4">Step {{ $currentStep }} of 3
@if ($currentStep == 1)
class="block text-sm">Name type="text" wire:model="name" class="border rounded-lg p-2 w-full"> @error('name') class="text-red-500 text-sm">{{ $message }} @enderror class="block mt-2 text-sm">Email type="email" wire:model="email" class="border rounded-lg p-2 w-full"> @error('email') class="text-red-500 text-sm">{{ $message }} @enderror
@endif @if ($currentStep == 2)
class="block text-sm">Address type="text" wire:model="address" class="border p-2 w-full"> @error('address') class="text-red-500 text-sm">{{ $message }} @enderror class="block mt-2">City type="text" wire:model="city" class="border p-2 w-full"> @error('city') class="text-red-500 text-sm">{{ $message }} @enderror
@endif @if ($currentStep == 3)
class="block">Gender wire:model="gender" class="border p-2 w-full"> value="male">Male value="female">Female
@endif class="mt-4 flex justify-between"> @if ($currentStep > 1) wire:click="previousStep" class="px-4 py-2 bg-gray-500 text-white rounded">Back @endif @if ($currentStep < 3) <button wire:click="nextStep" wire:loading.class="opacity-50" class="px-4 py-2 bg-blue-500 text-white rounded"> wire:loading.remove>Next wire:loading> Loading.. @else wire:click="nextStep" wire:loading.class="opacity-50" class="px-4 py-2 bg-green-500 text-white rounded"> wire:loading.remove>Save wire:loading> Loading.. @endif