[Django]-React routing and django url conflict

40👍

The issue is probably that you haven’t configured your URLs to handle the routes that are defined in React Router. In your Django urls.py you should be using a catch all to match all URLs to your index template

urlpatterns += [
    # match the root
    url(r'^$', base_view),
    # match all other pages
    url(r'^(?:.*)/?$', base_view),
]

The base_view would be a view function that renders a template which includes your bundled app.

28👍

In case anyone has this same problem, in django 2.0, follow ‘Kevin Martin Jose’ answer but instead, replace url with re_path

from django.urls import path, re_path

urlpatterns = [
    path('login/', LoginView.as_view(), name='login'),
    path('logout/', LogoutView.as_view()),
    path('/', login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
    re_path(r'^(?:.*)/?$', login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
]

7👍

In case someone’s wondering, I had the exact problem and Paul S’s answer solved it. Adding an answer instead of comment only because SO does not let me format code snippets inside comments. I ended up using a mixture of django’s new path() and the old urls() in my urls.py:

urlpatterns = [
    path('login/', LoginView.as_view(), name='login'),
    path('logout/', LogoutView.as_view()),
    path('/', login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
    url(r'^(?:.*)/?$',    login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
]

Django handles the login, logout and the root /. React router handles everything else

4👍

Here is an answer inspired by the Kevin Jones and Paul S answers. I was having issues with the regex and hosting a REST API. If my front-end app ever didn’t append the slash when making API calls, it wouldn’t match and it would get routed back to the front end. This is because the django setting APPEND_SLASH=True requires that it goes through urlpatterns and fails once before it appends the slash and tries again. Therefor, here is a regex that just excludes anything starting with ‘api’ or ‘admin’ and otherwise sends it on to the front end.

urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include(router.urls)),  # from rest_framework
re_path('(^(?!(api|admin)).*$)',
    TemplateView.as_view(template_name="build/index.html")),
] 

1👍

Here’s a solution that does not cause overrides of other views, and doesn’t require you to trash your 404 handler.

The disadvantage is this requires keeping an up-to-date list of your routes, but that’s what this file is meant for.

In urls.py:

from django.urls import re_path
from myapp import views

# This wrapper turns your list into a regex URL matcher
react_views_regex = r'\/|\b'.join([

    # List all your react routes here
    'view1',
    'view2'

]) + r'\/'

urlpatterns = [
    # Change views.index to whatever your view is
    re_path(react_views_regex, views.index),
]

These URLs should work with or without a trailing slash, are case-sensitive (like real routes), and will only match the full word (so views like ‘user’ and ‘users’ will not conflict).

0👍

Use HashRouter instead of BrowserRouter or manually type react-router-dom path in Django application (app) urls.

Leave a comment