
In this part of this tutorial we will begin installing reactjs dependencies through npm. Then we will setup reactjs in our laravel app and start creating our UI.
The first step when using reactjs in your laravel app is to tell laravel to switch the Javascript environment to use react, because laravel by default comes with Vuejs already you can find that in resources/js. So let’s run this command in the terminal:
php artisan preset react
This command will convert all vuejs components to reactjs components, and also it update package.json to include react and react-dom instead of vuejs.
The second step is to install npm dependencies with:
npm install
Great, now after installing react we need to create the main view home page which will display our react app. We will need two views as we will have two react apps one for the admin panel and the other for the website so open routes/web.php and update it with this code:
// Website route Route::get('/{path?}', function () { return view('website'); })->where('path', '[^admin]*'); // Admin route Route::get('/admin/{path?}', function () { return view('admin'); })->where('path', '.*');
The above routes uses laravel conditional routing using where() method and passing regular expression. The first route represent the website home and return a simple view. Here the path parameter will match anything except admin keyword. The second route represent the admin panel so the path parameter will match anything after /admin.
Â
Website & Admin Views
Create a new blade view resources/views/website.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 Laravel Blog</title> <!-- Fonts --> <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div id="app"></div> <script src="{{ asset('js/website.js') }}" type="text/javascript"></script> </body> </html>
Create another view resources/views/admin.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 Laravel Blog | Admin</title> <!-- Fonts --> <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div id="app"></div> <script src="{{ asset('js/admin.js') }}" type="text/javascript"></script> </body> </html>
The website and admin view will contain the react app. First i included the bootstrap stylesheet, at the bottom i included js/website.js andjs/admin.js. This is the compiled script after you run npm run dev or npm run watch as we will see shortly. Finally i added a simple div with #id=app which will render the reactjs app.
Let’s run
npm run dev
Go to http://localhost/react-laravel-blog/public or http://localhost/react-laravel-blog/public/admin
you will see a blank page for now because we have to do some modifications to the react app located in resources/js.
Main React Components
We will need two apps, the first for the website and the second for the admin. So we will create two sets of components for both apps.
Go to resources/js and create the below file structure:
Insert this code into resources/js/admin.js
require('./bootstrap'); require('./admin/App');
Also insert this code into resources/js/website.js
require('./bootstrap'); require('./website/App');
resources/js/admin/App.js
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; export default class App extends Component { render() { return ( <div className="container-fluid"> <div className="row justify-content-center"> <div className="col-md-8"> <div className="card"> <div className="card-header">Hello</div> <div className="card-body">I'm the admin panel</div> </div> </div> </div> </div> ); } } if (document.getElementById('app')) { ReactDOM.render(<App />, document.getElementById('app')); }
resources/js/website/App.js
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; export default class App extends Component { render() { return ( <div className="container-fluid"> <div className="row justify-content-center"> <div className="col-md-8"> <div className="card"> <div className="card-header">Hello</div> <div className="card-body">I'm the website</div> </div> </div> </div> </div> ); } } if (document.getElementById('app')) { ReactDOM.render(<App />, document.getElementById('app')); }
As you see above this is the file structure for the two react apps. Each app has a main component which in this case admin/App.js and website/App.js. we just add a dummy content for now and we will update it later.
Updating webpack.mix
There is one final thing so that the javascript compiled successfully is to update webpack.mix.js located in the root of your project like shown below
webpack.mix.js
const mix = require('laravel-mix'); /* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- */ mix.react('resources/js/admin.js', 'public/js') .react('resources/js/website.js', 'public/js') .sass('resources/sass/app.scss', 'public/css');
Now run npm run watch and refresh the page you will see the hello message.
Preparing Admin Panel Layout
For the purpose of this tutorial i use AdminLTE the free admin panel template. I downloaded the template and removed the unneeded styles and scripts, you can download it from here. Then extract it into a folder called assets/ in the public/ directory, if you don’t find assets/ directory just create it.
Update resources/views/admin.blade.php as follows:
<!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 Laravel Blog | Admin</title> <!-- Bootstrap 3.3.7 --> <link rel="stylesheet" href="{{ asset('assets/admin') }}/bower_components/bootstrap/dist/css/bootstrap.min.css"> <!-- Font Awesome --> <link rel="stylesheet" href="{{ asset('assets/admin') }}/bower_components/font-awesome/css/font-awesome.min.css"> <!-- Theme style --> <link rel="stylesheet" href="{{ asset('assets/admin') }}/dist/css/AdminLTE.min.css"> <!-- Theme skin --> <link rel="stylesheet" href="{{ asset('assets/admin') }}/dist/css/skins/skin-green.css"> <!-- bootstrap wysihtml5 - text editor --> <link rel="stylesheet" href="{{ asset('assets/admin') }}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> <!-- Google Font --> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> </head> <body class="hold-transition skin-green sidebar-mini"> <div id="app"></div> <!-- Main app script --> <script src="{{ asset('js/admin.js') }}" type="text/javascript"></script> <!-- jQuery 3 --> <script src="{{ asset('assets/admin') }}/bower_components/jquery/dist/jquery.min.js"></script> <!-- Bootstrap 3.3.7 --> <script src="{{ asset('assets/admin') }}/bower_components/bootstrap/dist/js/bootstrap.min.js"></script> <!-- Bootstrap WYSIHTML5 --> <script src="{{ asset('assets/admin') }}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <!-- AdminLTE App --> <script src="{{ asset('assets/admin') }}/dist/js/adminlte.min.js"></script> <!-- AdminLTE for demo purposes --> <script src="{{ asset('assets/admin') }}/dist/js/demo.js"></script> </body> </html>
I updated the view with styles and scripts needed for our template. Let’s refactor this template into partials. To do this this must be done in react code.
Updating React Main Component
Create a new directory called partials/ inside resources/js/admin/components which will contain partial components:
- Header.js
- Sidebar.js
- Footer.js
resources/js/admin/components/partials/Header.js
import React from 'react'; const Header = (props) => { return ( <header className="main-header"> <a href="#" className="logo"> <span className="logo-mini"><b>B</b>RL</span> <span className="logo-lg"><b>Blog</b>RL</span> </a> <nav className="navbar navbar-static-top"> <a href="#" className="sidebar-toggle" data-toggle="push-menu" role="button"> <span className="sr-only">Toggle navigation</span> </a> <div className="navbar-custom-menu"> <ul className="nav navbar-nav"> <li className="dropdown user user-menu"> <a href="#" className="dropdown-toggle" data-toggle="dropdown"> <img src="dist/img/user2-160x160.jpg" className="user-image" alt="User Image" /> <span className="hidden-xs">Alexander Pierce</span> </a> <ul className="dropdown-menu"> <li className="user-header"> <img src="dist/img/user2-160x160.jpg" className="img-circle" alt="User Image" /> <p> Alexander Pierce - Web Developer <small>Member since Nov. 2012</small> </p> </li> <li className="user-body"> </li> <li className="user-footer"> <div className="pull-left"> <a href="#" className="btn btn-default btn-flat">Profile</a> </div> <div className="pull-right"> <a href="#" className="btn btn-default btn-flat">Sign out</a> </div> </li> </ul> </li> </ul> </div> </nav> </header> ) } export default Header
resources/js/admin/components/partials/Sidebar.js
import React from 'react'; const Sidebar = (props) => { return ( <aside className="main-sidebar"> <section className="sidebar"> <div className="user-panel"> <div className="pull-left image"> <img src="dist/img/user2-160x160.jpg" className="img-circle" alt="User Image" /> </div> <div className="pull-left info"> <p>Alexander Pierce</p> </div> </div> <ul className="sidebar-menu" data-widget="tree"> <li className="header">MAIN NAVIGATION</li> <li className="active"> <a href="#"> <i className="fa fa-dashboard"></i> <span>Dashboard</span> <span className="pull-right-container"> <i className="fa fa-angle-left pull-right"></i> </span> </a> </li> <li> <a href="#"> <i className="fa fa-th"></i> <span>Posts</span> </a> </li> <li> <a href="#"> <i className="fa fa-list"></i> <span>Categories</span> </a> </li> <li> <a href="#"> <i className="fa fa-tags"></i> <span>Tags</span> </a> </li> <li> <a href="#"> <i className="fa fa-comments-o"></i> <span>Comments</span> </a> </li> <li> <a href="#"> <i className="fa fa-users"></i> <span>Users</span> </a> </li> </ul> </section> </aside> ) }; export default Sidebar;
resources/js/admin/components/partials/Footer.js
import React from 'react'; const Footer = (props) => { return ( <footer className="main-footer"> <div className="pull-right hidden-xs"> <b>Version</b> 2.4.0 </div> <strong>Copyright © 2014-2016.</strong> All rights reserved. </footer> ) }; export default Footer;
I used function based components here for now in these partial components. Now we need to update App.js and inject these components.
Open resources/js/admin/App.js and update as follows:
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import Header from './components/partials/Header'; import Sidebar from './components/partials/Sidebar'; import Footer from './components/partials/Footer'; export default class App extends Component { render() { return ( <div className="wrapper"> <Header/> <Sidebar/> <div className="content-wrapper"> </div> <Footer/> </div> ); } } if (document.getElementById('app')) { ReactDOM.render(<App />, document.getElementById('app')); }
In terminal initiate
npm run dev
and refresh the page you will see the green admin panel.
Continue to part4: React Admin Panel
Can you please share register with email verification code using react?
You can make this manually by tweaking the RegisterController.php or you can use a ready made package such as https://github.com/jrean/laravel-user-verification
– To manually verify emails update the RegisterController::register and send an email message to the user email address.
– Then make a new component in reactjs so that the user can be redirected to when verifying emails