In this blog post we will create a simple laravel 8 app to learn how to use the React router alongside Laravel 8.
Sometimes when working with laravel you may face scenarios when you want to display some sort of dynamic widget or complex form. The widget i am talking about here is something more complex to do using normal javascript libraries such as Jquery.
An example of this is that i was recently working on a Laravel project, and one of the requirements in the project was to create a multi-step form. The multi-step form must reflect each step the user is currently in the browser url. And als0 the navigation through each step must be smooth with reloading the browser.
For this purpose, we used the React on this page with the React Router to display the steps of the form.
So let’s start by creating a laravel 8 project
composer create-project laravel/laravel:8.x.x lara_8_react_router --prefer-dist
cd into the project directory
cd lara_8_react_router
Install laravel/ui
composer require laravel/ui
Next run this command to generate React scaffolding:
php artisan ui react
Then install npm dependencies:
npm install
Run laravel mix:
npm run dev
Now the javascript assets compiled successfully and a new javascript file app.js is generated in public/js/app.js.
Creating React Component
If you view the resources/js directory you will see a couple of files. The app.js, bootstrap.js and components directory. Those files automatically generated using laravel/ui command.
In the components directory there is just one react component Example.js, rename the file to MyApp.js and update it’s contents as below:
components/MyApp.js
import React from 'react'; import ReactDOM from 'react-dom'; function MyApp() { return ( <div className="container"> <div className="row justify-content-center"> <div className="col-md-8"> <h2>I am react app</h2> </div> </div> </div> ); } export default MyApp; if (document.getElementById('app')) { ReactDOM.render(<MyApp />, document.getElementById('app')); }
Update resources/js/app.js
require('./bootstrap'); require('./components/MyApp');
Don’t forget to run:
npm run dev
Let’s create a simple view to serve our react app.
Create resources/views/reactapp.blade.php
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>React App</title> <!-- Fonts --> <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet"> <style> body { font-family: 'Nunito', sans-serif; } </style> <link href="{{mix('css/app.css')}}" type="text/css" rel="stylesheet" /> </head> <body class="antialiased"> <!-- React DOM Node --> <div id="app"></div> <script type="text/javascript" src="{{mix('js/app.js')}}"></script> </body> </html>
Next update routes to point at this view:
routes/web.php
<?php use Illuminate\Support\Facades\Route; Route::view('/{path?}', 'reactapp') ->where('path', '.*');
The most interesting in this route is the ->where() method. This tells laravel to redirect anything coming after / to the react app, for example if you go to “/page” it will also show the same react app.
Now if you launch the project and navigate to localhost:8000 you will see “I am React app” text which means that react component successfully mounted.
php artisan serve
React Router
Install react router first:
npm install react-router-dom@6
In order to setup the router we will need some pages to assign them to the router so let’s create some pages.
In js/components directory create a new directory pages/ with the following components:
- pages/Home.js
- pages/About.js
- pages/Contact.js
Home.js
import React from "react"; function Home() { return ( <div className="container"> <div className="row justify-content-center mt-3"> <div className="col-md-8"> <h2>Home page</h2> </div> </div> </div> ); } export default Home;
About.js
import React from "react"; function About() { return ( <div className="container"> <div className="row justify-content-center mt-3"> <div className="col-md-8"> <h2>About page</h2> </div> </div> </div> ); } export default About;
Contact.js
import React from "react"; function Contact() { return ( <div className="container"> <div className="row justify-content-center mt-3"> <div className="col-md-8"> <h2>Contact page</h2> </div> </div> </div> ); } export default Contact;
The final step is to tell the router to map each page to a route path, this is done in the MyApp.js component:
MyApp.js
import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; function MyApp() { return ( <Routes> <Route path="/" element={<Home /> } /> <Route path="/about" element={<About /> } /> <Route path="/contact" element={<Contact /> } /> </Routes> ); } export default MyApp; if (document.getElementById('app')) { ReactDOM.render( <BrowserRouter> <MyApp /> </BrowserRouter> , document.getElementById('app')); }
In this code we imported some assets like BrowserRouter, Routes and Route components. Next in the MyApp render() method we return all routes using the <Route /> component wrapped by <Routes /> component.
Each <Route /> component have a path and element props. The path is the url the user navigate to, and the element is the react component to be displayed when navigating to this path.
Note that in previous versions of react router the element prop has another name which is component.
Also in ReactDOM.render() we wrapped the <MyApp /> component with <BrowserRouter /> component.
To test this you must run again:
npm run dev
And go to each page like “/” or “/about” or “/contact” you will see the right page is displaying.
Displaying Links
In a real world app the user won’t type the url directly into the browser address bar. So it’s better to have some kind of menu or navbar so the user can move easily to each page by clicking a link.
Create components/Navbar.js
import React from "react"; import {Link} from "react-router-dom"; function Navbar() { return ( <div className="container"> <nav className="navbar navbar-expand-lg navbar-light" style={{backgroundColor: "#e3f2fd"}}> <Link to="/" className="navbar-brand">React App</Link> <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span> </button> <div className="collapse navbar-collapse" id="navbarText"> <ul className="navbar-nav mr-auto"> <li className="nav-item active"> <Link to="/" className="nav-link">Home</Link> </li> <li className="nav-item"> <Link className="nav-link" to="/about">About</Link> </li> <li className="nav-item"> <Link className="nav-link" to="/contact">Contact</Link> </li> </ul> </div> </nav> </div> ); }; export default Navbar;
Now inject this Navbar component in the main component MyApp.js
import Navbar from "./Navbar"; function MyApp() { return ( <> <Navbar /> <Routes> <Route path="/" element={<Home /> } /> <Route path="/about" element={<About /> } /> <Route path="/contact" element={<Contact /> } /> </Routes> </> ); }
Again run
npm run dev
Now you will see the navbar links, you can click any link to navigate to each page.
This article solid my concept about routing in react. Person teach in very short but delivering comprehensive. We should appreciate for their efforts.
Thanks