score:-2

i believe i found a possible setup.

include the react-router routes on symfony's routes.yaml, all pointing to the same controller that generates react's root component.

all other routes, like for api calls, would be set up normally.

//config/routes.yaml
//all routes handled by pwa(react-router) pointing to same controller
home:
   path: /
   controller: app\controller\indexcontroller::index

account:
   path: /account
   controller: app\controller\indexcontroller::index

if somebody knows an alternative setup, please share.

score:4

the proper approach to this problem is setting route annotation like this:

/**
* @route("/{reactrouting}", name="index", priority="-1", defaults={"reactrouting": null}, requirements={"reactrouting"=".+"})
*/
public function index(): response
{
    return $this->render('index.html.twig');
}

the magic here is to use "priority=-1" parameter. this allows symfony to use routing to find proper path for api methods, and only if no route was found, react router starts, looking for its route. if there is no react route as well you should handle it using some "notfound" component in react app.

with this approach you can still use spa, but also define all logic and use api in the same app.

score:12

a solution could be following.

the controller with route annotation, all routes will be handled by react with this annotation, no matter how many parameters the route might have:

namespace app\controller;

use sensio\bundle\frameworkextrabundle\configuration\template;
use symfony\bundle\frameworkbundle\controller\controller;
use symfony\component\routing\annotation\route;

class defaultcontroller extends controller
{
    /**
     * @template("default/index.html.twig")
     * @route("/{reactrouting}", name="index", requirements={"reactrouting"=".+"}, defaults={"reactrouting": null})
     */
    public function index()
    {
        return [];
    }
}

if you have routes that shouldn't be handled by react, your annotation could exclude them like as follows - all routes that start with api will not be handled by react:

@route("/{reactrouting}", name="index", requirements={"reactrouting"="^(?!api).+"}, defaults={"reactrouting": null})

twig template, with root element:

{% extends 'base.html.twig' %}

{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/js/app.css') }}">
{% endblock %}

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

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

react index file:

import react from 'react';
import reactdom from 'react-dom';
import {browserrouter, route, switch} from 'react-router-dom';

import home from "./containers/home";
import aboutus from "./containers/aboutus";


reactdom.render(
       <browserrouter>
            <switch>
                <route path="/" component={home}/>
                <route path="/about-us" component={aboutus}/>
            </switch>
        </browserrouter>,
    document.getelementbyid('root'));

and my encore config:

var encore = require('@symfony/webpack-encore');

encore
    // the project directory where compiled assets will be stored
    .setoutputpath('public/build/')
    // the public path used by the web server to access the previous directory
    .setpublicpath('/build')
    .cleanupoutputbeforebuild()
    .enablesourcemaps(!encore.isproduction())
    // uncomment to create hashed filenames (e.g. app.abc123.css)
    // .enableversioning(encore.isproduction())

    // uncomment to define the assets of the project
    // .addentry('js/app', './assets/js/app.js')
    // .addstyleentry('css/app', './assets/css/app.scss')

    // uncomment if you use sass/scss files
    // .enablesassloader()

    // uncomment for legacy applications that require $/jquery as a global variable
    // .autoprovidejquery()

    .enablereactpreset()
    .addentry('js/app', './react/index.js')
    .configurebabel((config) => {
        config.presets.push('stage-1');
    })
;

module.exports = encore.getwebpackconfig();

Related Query

More Query from same tag