React rendered components from Django doesn't show after reloading

Question:

I have a Django project that emits Javascript(ReactJS) to the browser as frontend. It’s an SSR app — Django renders a view with a template that loads a React script.

Everything works just fine except when I go to a different page(React component routed with React-router) and reload the browser. The Django server routes the URL to a pattern that doesn’t exist in URLconf, hence the interference with react components that result in a Django 404 error.

Is there a workaround to solve this?

PS: I chose this method rather than the decoupled method for compatibility and testing purposes.

Below are the essential parts that relate the issue:

Backend

urls.py

from django.urls import path

from frontend import views

urlpatterns = [
    path("", views.react_template, name="react_template"),
]

views.py

from django.shortcuts import render


def react_template(request):
    return render(request, "template.html", {"title": "Chatter"})

template

from django.urls import path

from frontend import views

urlpatterns = [
    path("", views.react_template, name="react_template"),
]

Frontend

App.js

import React, { useEffect, Fragment } from "react";
import ReactDOM from "react-dom";

import webSocketInstance from "../utils/websocket";
import PrivateRoute from "../utils/privateRoute";

// ...
import Chat from "./chat/chat";
import CreateRoom from "./chat/room";

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

export default function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route path="/" exact component={Index} />
        <Route
          path="/login"
          render={() => <Login />}
        />
        <Route path="/signup" render={() => <Signup />} />
        <PrivateRoute path="/room">
          <CreateRoom />
        </PrivateRoute>
        <PrivateRoute path="/chat">
          <Chat />
        </PrivateRoute>
      </Switch>
    </BrowserRouter>
  );
}

Index.js

import React from "react";
import ReactDOM from "react-dom";

import { Provider } from "react-redux";

import App from "./components/app";
import store from "./states/store";

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById("app")
);
Asked By: Romeo

||

Answers:

I am not sure what the optimal solution for you is but this one could work

urlpatterns = [
    path("", views.react_template), 
    re_path(r'^.*', views.react_template),
]

The second one should catch all paths

Answered By: Ahmed Nasr