Serving static React.js content with Django (part 1)

Photo by Milada Vigerova on Unsplash

Preface

I had a relatively simple SPA written with react.js, it was deployed on Netlify. At the time I’ve had no problems with that setup, but then I started thinking about new features to introduce by implementing backend functionality, and the thought of having a backend working on a different server (afaik Netlify doesn’t support Django out of the box) for such a small app as mine was daunting, not to mention all the routing problems with having it all under one domain name.
I’ve decided that my SPA didn’t need a whole server to host few of it’s static files and thought of using Django to serve them (which is kind of an oversimplification but we’ll get to it). I have also wanted to try out Kubernetes and see if I could create a working setup for my app with it. Skipping forward, now I have a Digital Ocean K8's cluster that has two replicas of two pods each, one of the pods is running a dockerized nginx web-server and the other is a dockerized Django REST app, both of ’em having a shared volume space for static content.

reject create-react-app, embrace webpack

There are some complications that come with creating a Django/React fusion. Originally I’ve had my simple app use create-react-app package, but that takes care of too many things for you. That might be okay if you are, like I had it in the beginning, lacking any sort of backend functionality whatsoever. Django, on the other end, has a weird way of dealing with static files (and simply doesn’t understand javascript), and having no control over the react build bundle imposes too many constraints on your final setup, especially if you are using PWA features.

creating a simple django app

make a virtual environment & activate it

D:\>python -m venv tutorialenvD:\>tutorialenv\Scripts\activate

create react app without create-react-app

Navigate outside of your Django folder and create a new one wherever and call it whatever, I’ll call it tutorialreact

{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}

Creating an html template

Get back to the Django folder and create a templates directory at the root of the project. Let’s put a dead simple index.html inside of it:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'apps.indexview',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR, 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

Making Django serve React app

We have our react app compiled down to a single js file, and can simply link it in our html template, just as we would with any other react app. Create a new directory build in the root of your Django project folder, then create another folder inside it called js and paste the index_bundle.js we got from running npm run build

STATICFILES_DIRS = [
BASE_DIR / "build",
]

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store