Contents
Good day, welcome to this blog. Today I will be showing you how to develop a react single-page application(SPA) in Laravel 9. Before we proceed let’s have a little bit of discussion.
A Single Page Application (SPA) is a web application or website that utilized only a single page and dynamically changes its content. The page does not reload unlike Multiple Page Application (MPA) which reloads pages to display new information.
Laravel is a free, open-source PHP Web Framework intended for the development of web applications following the MVC (Model-View-Controller) architectural pattern. It is designed to make developing web apps faster and easier by using built-in features.
React or also called React.js or Reactjs is a free and open-source JavaScript library used for building user interfaces(UI). It is one of the most popular JavaScript libraries for building the front-end. React is created by Facebook and maintained by Facebook.
Step 1: Install Laravel 9
First, select a folder that you want the Laravel to be installed then execute this command on Terminal or CMD to install Laravel 9:
Install via composer:
composer create-project laravel/laravel laravel-9-react-spa
Install via Laravel Install:
laravel new laravel-9-react-spa
Step 2: Setup Front-end Scaffolding
Let’s install the laravel/ui package:
composer require laravel/ui
Then we can now install the react front-end scaffolding:
php artisan ui react
npm install
We will then install react-router-dom, this will be used for the routing system of our app.
npm install react-router-dom
Step 3: Create View File
After installing the necessary packages, we will then create a view file that will be used for our react application. Create a file in /resources/views/app.blade.php and add these codes:
/resources/views/app.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>LARAVEL REACT SPA</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
Step 4: Register A Route
After creating the view file, we will register a route in /routes/web.php. Remove the default route on the file and register this route.
/routes/web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::view('/{path?}', 'app');
Step 5: Run the Application
To test if our app is running:
Execute this command to run our Laravel App:
php artisan serve
And then run this command to watch file changes:
npm run watch
Open this URL to check if we have no errors.
http://localhost:8000/
Step 6: Create The React Files
We will now start creating our react files. We will create these files inside /resources/js directory. These will be what the file structure looks:
You can have your own way of managing or structuring your files.
Let’s create the Main.js file – In this file we are the one that handles the routing:
resources/js/Main.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./pages/Home"
import Blog from "./pages/Blog"
import About from "./pages/About"
import Contact from "./pages/Contact"
import NotFound from "./pages/NotFound"
function Main() {
return (
<Router>
<Routes>
<Route exact path="/" element={<Home/>} />
<Route path="/blog" element={<Blog/>} />
<Route path="/about" element={<About/>} />
<Route path="/contact" element={<Contact/>} />
<Route element={<NotFound/>} />
</Routes>
</Router>
);
}
export default Main;
if (document.getElementById('app')) {
ReactDOM.render(<Main />, document.getElementById('app'));
}
After creating the Main.js file, let’s update the app.js file:
resources/js/app.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes React and other helpers. It's a great starting point while
* building robust, powerful web applications using React + Laravel.
*/
require('./bootstrap');
/**
* Next, we will create a fresh React component instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
require('./Main');
Inside the /resources/js/components folder, let’s create a files named Layout.js and Header.js – this will serve as a template. And also you can delete the Example.js file.
/resources/js/components/Layout.js
import React from 'react';
const Layout =({children}) =>{
return(
<div className="container">
{children}
</div>
)
}
export default Layout;
/resources/js/components/Header.js
import React, {useEffect} from 'react';
import { Link, useLocation } from "react-router-dom";
function Header() {
const location = useLocation();
const pageLinks = [
{
"name": "Home",
"url" :"/",
},
{
"name": "Blog",
"url" :"/blog",
},
{
"name": "About",
"url" :"/about",
},
{
"name": "Contact",
"url" :"/contact",
},
];
useEffect(() => {
pageLinks.map((page)=>{
if(page.url == location.pathname) {
document.title = page.name;
}
});
}, [])
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<Link to="/" className="navbar-brand">Binaryboxtuts</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
{
pageLinks.map((page, key) => {
return (
<li key={key} className={`nav-item ${location.pathname == page.url ? 'active' : ''}`}>
<Link to={page.url} className="nav-link">{page.name}</Link>
</li>
)
})
}
</ul>
</div>
</nav>
);
}
export default Header;
We will now create a folder in /resources/js named pages. Inside the folder let’s create these files for our pages:
- Home.js
- Blog.js
- About.js
- Contact.js
- NotFound.js
/resources/js/pages/Home.js
import React from 'react'
import Layout from "../components/Layout"
import Header from '../components/Header'
function Home() {
return (
<Layout>
<Header/>
<div className="container">
<h2 className="text-center mt-5 mb-3">Home Page</h2>
</div>
</Layout>
);
}
export default Home;
/resources/js/pages/Blog.js
import React from 'react'
import Layout from "../components/Layout"
import Header from '../components/Header'
function Blog() {
return (
<Layout>
<Header/>
<div className="container">
<h2 className="text-center mt-5 mb-3">Blog Page</h2>
</div>
</Layout>
);
}
export default Blog;
/resources/js/pages/About.js
import React from 'react'
import Layout from "../components/Layout"
import Header from '../components/Header'
function About() {
return (
<Layout>
<Header/>
<div className="container">
<h2 className="text-center mt-5 mb-3">About Page</h2>
</div>
</Layout>
);
}
export default About;
/resources/js/pages/Contact.js
import React from 'react'
import Layout from "../components/Layout"
import Header from '../components/Header'
function Contact() {
return (
<Layout>
<Header/>
<div className="container">
<h2 className="text-center mt-5 mb-3">Contact Page</h2>
</div>
</Layout>
);
}
export default Contact;
/resources/js/pages/NotFound.js
import React from 'react'
import Layout from "../components/Layout"
import Header from '../components/Header'
function NotFound() {
return (
<Layout>
<Header/>
<div className="container">
<h2 className="text-center mt-5 mb-3">404 | Page Not Found</h2>
</div>
</Layout>
);
}
export default NotFound;
We’re all done, what is left is to test the pages. Open this URL:
http://localhost:8000/
Screenshots:
Home Page
Blog Page
About Page
Contact Page
404 Page