vintasoftware / django-react-boilerplate

Django 5, React, Bootstrap 5 with Python 3 and Webpack project boilerplate
MIT License
1.97k stars 479 forks source link

Getting react router working with Django #559

Open educepter opened 2 years ago

educepter commented 2 years ago

Describe the bug The boilerplate code works for me. After integrating my backend, am able to query it through Postman and get expected responses. From frontend, I could see the div with "react-app" id replaced with my frontend, for the landing page.

However, my frontend uses "react-router-dom", and need to serve many paths/urls. If I just try to navigate to another path in my frontend, I get a 404 with the following error (with DEBUG=True in Django):

Using the URLconf defined in myproject.urls, Django tried these URL patterns, in this order:
[name='index']
admin/
jsreverse/ [name='js_reverse']
api/v0/auth/
api/v0/

Could you please help how to serve multiple paths from frontend with this boilerplate code. Thanks!

To Reproduce Steps to reproduce the behavior:

  1. Add a react router in frontend with 'react-router-dom'

Expected behavior Be able to serve multiple paths from the frontend.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context Add any other context about the problem here.

educepter commented 2 years ago

Got this working. One of the components in my frontend was erroring out, and the entire frontend wasn't getting rendered. Also, one other related issue I faced was that not all paths (apart from the home page URL) were caught by Django. Fixed this by changing path to re_path in Django.

terrynguyen255 commented 10 months ago

For ones who are new (just like me), to add about page you need to:

backend/common/urls.py

urlpatterns = [
-    path("", views.IndexView.as_view(), name="index"),
+    re_path("", views.IndexView.as_view(), name="index"),
+    re_path("/about", views.IndexView.as_view(), name="index"),
]

frontend/js/App.js

const App = () => (
  <Sentry.ErrorBoundary fallback={<p>An error has occurred</p>}>
    <Provider store={store}>
-     <Home />
+      <BrowserRouter>
+        <Routes>
+          <Route path="/" index element={<Home />} />
+          <Route path="/about" index element={<About />} />
+        </Routes>
+      </BrowserRouter>
    </Provider>
  </Sentry.ErrorBoundary>
);

However, I'm still very confused about why do routes need to be managed & declared at both BE & FE side. That looks redundant & not DRY to me. @educepter @fjsj @chocoelho and other gurus, could you enlighten me 🙏 ?

fjsj commented 10 months ago

@terrynguyen255 to avoiding repeating routes in backend/frontend, you need to catch all possible frontend routes in a single URL conf in Django, and direct all of them to IndexView or similar.

An easy way to do this is to put a catch-all URL pattern as your final one, like this: https://stackoverflow.com/a/71836642 Then you could ensure your backend routes all have a common prefix too, like api/ and put that before the catch-all pattern.

I will re-open this issue to document this better in the README for other users. But you don't need anything specific from this boilerplate to solve this issue. Let me know if you still have questions.