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")
);
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
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")
);
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