1

I'm writing a django rest framework API (backend) with a react SPA frontend. For the production environment, the front end is served up via nginx at http://example.com/ and the backend is proxied to gunicorn and served from the same domain with a different path - http://example.com/api/

This is all working fine in production, there are no CORS issues as the frontend and backend are both served up under the same domain via nginx.

For local development, I want to be able to replicate a similar setup using ./manage.py runserver and have django serve up the frontend from project/frontend/dist (built by npm build seperately).

Has anyone got any urlpattern wizardry that will allow this to happen and also let the react-router play nicely? I just can't figure it out and it's starting to drive me nuts...

The project structure is something like this if it helps in any explanations.

Project
|
 ── backend
│   ├── apps
│   ├── config
|   |    ├── settings.py
|   |    ├── settings_local.py
|   |    ├── urls.py
│   ├── manage.py
│   ├── requirements.txt
│   └── venv
├── frontend
│   ├── dist (contains the npm build webpack)
│   ├── node_modules
│   ├── package.json
│   ├── package-lock.json
│   ├── scripts
│   ├── src
│   ├── webpack.config.js

Edit #1

Thanks to another post I was able to get partially the way there by adding this to my urls.py

if settings.DEBUG:
    from django.views.generic import RedirectView
    from django.contrib.staticfiles.views import serve

    bundle_path = os.path.abspath(os.path.join(root_dir, 'frontend', 'dist'))

    settings.STATICFILES_DIRS += (bundle_path,)

    urlpatterns += [url(r'^$', serve, kwargs={'path': 'index.html'})]
    urlpatterns += [url(r'^(?!/?static/)(?!/?media/)(?P<path>.*\..*)$',
        RedirectView.as_view(url='/static/%(path)s', permanent=False))]

The only issue I have here is that if I go directly to one of the JS router links, then django tries to interpret it and can't find the route.

What I need now is a catch-all that will redirect to '/' but also keep any extra URL path information on the url

2 Answers 2

2

Finally got this to work with all the routing.

Added the webpack dist folder to settings.STATICFILES_DIRS Added the webpack frontend path to settings.TEMPLATES

Added 3 new urlpatterns to urls.py ( based on a conditional, settings.DEBUG)

urlpatterns += [
        url(r'^(?!/?static/)(?!/?media/)(?P<path>.*\..*)$',
        RedirectView.as_view(url='/static/%(path)s', permanent=False)),
        url(r'^$', TemplateView.as_view(template_name='dist/index.html'), name='frontend'),
        url(r'^(?P<path>.*)/$', TemplateView.as_view(template_name='dist/index.html'), name='frontend'),
]

The first redirects any of the asssets for the bundle to be served using django's static files.

The second pattern serves the root path / as a template from the webpack dist folder

The final piece handles all the leftover JS routing paths to go back to the initial root view.

Sign up to request clarification or add additional context in comments.

Comments

0

You can use nginx reverse proxy to serve them. No need config Django's url. See example here: http://www.codingpedia.org/ama/how-to-configure-nginx-in-production-to-serve-angular-app-and-reverse-proxy-nodejs

1 Comment

This is what I am trying to avoid. Seems a little heavy for this scenario to use nginx locally (or docker).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.