Backend DevelopmentFrontend Development

Building a Blog With Reactjs And Laravel Part3: Begin Reactjs

Building a Blog With Reactjs And Laravel Part3

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:

reactjs laravel blog 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 &copy; 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

 

4.3 3 votes
Article Rating

What's your reaction?

Excited
2
Happy
2
Not Sure
4
Confused
4

You may also like

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Ankita Vekariya
Ankita Vekariya
4 years ago

Can you please share register with email verification code using react?