Building a Web App with Symfony and React : A Comprehensive Guide Part I

Faezbhatti
4 min readFeb 26, 2023

--

Symfony + React

Introduction

Symfony and React are two of the most popular technologies used in modern web development, and when combined, they provide a powerful toolset for building dynamic and responsive web applications.

Symfony is a PHP-based framework which is great to make a robust and secure backend, while React is a JavaScript library for building interactive interfaces with reusable components. Together, they provide developers flexible and powerful tools to build web applications that are both highly performant and user-friendly.

In this article, we’ll take a look into how to start a Symfony project and integrate React into it.

Development

First, start a new Symfony project :

symfony new my_react_symfony_project --version="5.4" --webapp

Here is what the flags at the end are for :

  • If you want to use a specific version of Symfony, you can specify with the version flag. Here I decided to use the LTS version, which is 5.4 as of today. But if you want to use the latest stable version just skip this.
  • With the webapp flag, you can install all necessary dependancies for a web app. If want to have a lighter version for your project or only install the dependancies you want, skip the webapp flag.

In case you chose to install the dependancies yourself, I recommend you to install the following packages with composer :

  • twig
  • symfony/maker-bundle — dev
  • orm
  • form
  • validator
  • twig-bundle
  • security-csrf
  • annotations

We also have to install Encore with composer :

composer require symfony/webpack-encore-bundle

Among other things, this will create the webpack.config.js which we’ll be using next.

In the webpack.config.js file, we have to uncomment the following line :

// ./webpack.config.js

Encore
...
// .enableReactPreset()

Add some dependancies for React :

npm install react react-dom prop-types --save
npm install @babel/preset-react@^7.0.0 --save-dev

Now, we can run the webpack server :

npm run dev-server

We also have to run Symfony server :

symfony serve # Launches a server on port 8000

Now that the installation is done, we can start developing your app.

First, generate a default controller :

symfony console make:controller DefaultController

Go into this new controller and change the route and function so that it matches the following code :

// src/Controller/DefaultController.php

#[Route('/', name: 'app_default')]
public function index(): Response
{
return $this->render('base.html.twig');
}

Once this is done, go to the base.html.twig template. Inside the body tag we can remove the block body and put this instead :

// templates/base.html.twig

<div id="app"></div>

It’s inside this div that our entire React app will be rendered.

Now we need some files that haven’t been generated during the configuration. When we create a new React project with this command :

npx create-react-app my-app

We get two files that we’ll be needing in our project : App.js & index.js. Let’s save us the trouble to create a new React project just for these. One advice : copy the content of index.js and paste it in app.js in order to use a single file.

/assets/app.js

import React from 'react';
import ReactDOM from 'react-dom/client';

import './styles/app.css';
import './bootstrap';

function App() {
return (
<div className="App">
<header>
<h1>React App</h1>
</header>
</div>
);
}

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

Let’s add some routes. We have to use the router in React for the navigation. Install this dependancy :

npm i -D react-router-dom

/assets/app.js

import { BrowserRouter, Routes, Route } from "react-router-dom";

function App() {
return (
<div className="App">
...
<BrowserRouter>
<Routes>
</Routes>
</BrowserRouter>
</div>
);
}

Create a new component and the route for it :

assets/components/Home.jsx

import React, { Component } from 'react'

export default class Home extends Component {
render() {
return (
<h2>Home</h2>
)
}
}

assets/app.js

import Home from './components/Home';

function App() {
...
<BrowserRouter>
<Routes>
<Route path="/">
<Route index element={<Home />} />
</Route>
</Routes>
</BrowserRouter>
}

Let’s also create another page.

assets/components/About.jsx

import React, { Component } from 'react'

export default class About extends Component {
render() {
return (
<h2>About</h2>
)
}
}

Make a Layout component for our app.

assets/components/Layout.jsx

import React from "react";
import { Outlet, Link } from "react-router-dom";

const Layout = () => {
return (
<>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>

<li>
<Link to="/about">About</Link>
</li>
</ul>
</nav>

<Outlet />
</>
)
};

export default Layout;

Update BrowserRouter in app.js :

<BrowserRouter>
<Routes>
<Route path="/" element={<Layout/>}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
</Route>
</Routes>
</BrowserRouter>

We can use the navigation with React but when we go to /about and try to refresh the page we’ll get a 404 error saying that there is no existing route for this url.

404 Error for /about

Which makes sense since we’ve only created /about on the client side. We have to do the same thing on the server side and so let’s create /about in the DefaultController which will also render the base template.

// src/Controller/DefaultController.php
...

#[Route('/about', name: 'about')]
public function about(): Response
{
return $this->render('base.html.twig');
}

Conclusion

We are now able to create an app using Symfony and React.

But we’ve mainly seen how to implement the React part here. So, in an upcoming article we’ll see how to use Symfony for the backend.

Here is the link to my repo on Github for this app : https://github.com/Faez-B/my_react_symfony_project

--

--