5
votes

I have a react frontend made with create-react-app to deploy a production build of this I just do npm run build. My app uses a Django Rest FrameWork API backend.

How can I setup the app for deployment on a single server. Is there a way I can store the React Frontend and route to it in Django and have requests from the Frontend hit a api/ view or endpoint.

What are the best strategies for deploying something like this or is it better to host the Frontend and Backend desperately on different servers?

Basically: How do I combine my react frontend build into Django DRF for deployment?

2

2 Answers

3
votes

You can use django as a container for your react app. Run "npm run build" inside your react project root folder. It will generate build directory and bundle all the javascript files. Put this build folder inside the root directory of your django project. and make the following changes in settings.py file:

STATICFILES_DIRS = (
    ...
     os.path.join(BASE_DIR, 'build/static'),
     os.path.join(BASE_DIR, 'build')
...
)

and in urls.py make an entry like :-

url(r'^$', mView.login, TemplateView.as_view(template_name = 'index.html'))

Make api calls from react app using 'axios' or native fetch api.

After this whenever you hit the url for your django project it'll be redirected to the react app. You can host this with apache wsgi. Works fine for me.

Following link might help: https://medium.com/alpha-coder/heres-a-dead-simple-react-django-setup-for-your-next-project-c0b0036663c6

0
votes

What I do is after serving the static content (built react app), there are entry points in the DRF API, which has a template, sets the server context (if you want to set any) in the clientConfig object.

Also, you will need to create a separate "initializer" script for each endpoint with react routes in it, providing it the right selector which you will mention in the Django Templates.

URL: path('foobars', views.FooBarsView.as_view(), name='foobars')

View:

class FooBarsView(TemplateView):
    template_name = 'foobars.html'

    def get_context_data(self):
        return {
            "client_config": {}
        }

Template (foobars.html):

{% load static from staticfiles %}

<head>
    <link rel="stylesheet" href="{% static 'dist/css/foobars.css' %}"/>
</head>

<main class="foobars"></main>

<script type="text/javascript">
    var clientConfig = {{ client_config|safe }};
</script>

<script type="text/javascript" src="{% static "dist/js/foobars.min.js" %}"></script>

Some changes in the React app you have to make, is to use the selector .foobars in the render method.

Initializer:

ReactDOM.render(
    <Provider store={store}>
        <Router history={history}>
            <Switch>
                <Route name="index" exact path="/" component={FooBarComponent} />
            </Switch>
        </Router>
    </Provider>,
    document.querySelector(".foobars")
);