Symfony 4 and ReactJS – Routing

In the previous article we learned how to setup ReactJS in our Symfony application. The next step is to add routing.

Routing is a key aspect of any application. We could create a ReactJS entry point for each route we define in Symfony. But its more preferable that we use the power of ReactJS. This means that we make a single page application, while still going through the Symfony router to bootstrap the application.

Installing the ReactJS Router

Before we can start we should install the React Router.

yarn add react-router-dom --dev

After this, we can change App.js to use routing by using BrowserRouter.

class App extends React.Component {
  render() {
    return (
        <BrowserRouter>
            <Switch>
              <Route path="/another-page" component={AnotherPage}/>
              <Route path="/" component={Dashboard}/>
            </Switch>
        </BrowserRouter>
    );
  }
}

You will notice the 2 Route’s that I defined in here. These will be our 2 pages we will use for testing purpose.

import React from 'react';

class Dashboard extends React.Component {
  render() {
    return (
        <div>
          <p>Welcome to the dashboard!</p>
        </div>
    );
  }
}

export default Dashboard;
import React from 'react';

class AnotherPage extends React.Component {
  render() {
    return (
        <div>
          <p>Welcome to another page!</p>
        </div>
    );
  }
}

export default AnotherPage;

We then import those in our App.js

import Dashboard from './pages/Dashboard/Dashboard';
import AnotherPage from './pages/AnotherPage/AnotherPage';

But of course, we also need a way to switch between the 2 pages. So let’s add a simple menu.

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, NavLink, Route, Switch} from 'react-router-dom';

import Dashboard from './pages/Dashboard/Dashboard';
import AnotherPage from './pages/AnotherPage/AnotherPage';

class App extends React.Component {
  render() {
    return (
        <BrowserRouter>
          <div>
            <ul>
              <NavLink to="/">Dashboard</NavLink>
              <NavLink to="/another-page">Another Page</NavLink>
            </ul>
            <Switch>
              <Route path="/another-page" component={AnotherPage}/>
              <Route path="/" component={Dashboard}/>
            </Switch>
          </div>
        </BrowserRouter>
    );
  }
}

Now our React JS side of the application is ready. The only thing remaining is to execute yarn run dev to build our new JavaScript.

Routing in Symfony

The entry of our application is handled by Symfony. We now need to create a controller which dynamically handles all the ReactJS routes.

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

final class IndexController extends Controller
{
    /**
     * @Route("/{reactRouting}", name="index", defaults={"reactRouting": null})
     */
    public function dashboard(): Response
    {
        return $this->render('pub/index.html.twig');
    }
}
{% extends 'base.html.twig' %}

{% block body %}
    <div id="root"><div>
{% endblock %}

{% block javascripts %}
    <script type="text/javascript" src="{{ asset('build/js/app.js') }}"></script>
{% endblock %}

If we now run our application you can go to / or /another-page and you will see the correct page that we defined in our ReactJS application.

This is a basic solution to handle routing with Symfony and ReactJS.