Learn the right way to combine Django and ReactJS. This article includes links to a public repository with a fully documented, fully-functional reference project that you can setup in less than an hour and run in your local dev environment using Docker.
If you’re looking for guidance on how to create React pages inside your Django project then you’re in the right place, so please keep reading. I maintain a fully-functional reference project in Github with quick start instructions to get it running locally in your development environment. I highly recommend that you take a look at this repo as part of your research. There are a number of small details codified in the repo which go unmentioned here for the sake of brevity. This article is really just supplemental narrative that explains my design objectives and implementation strategy.
In a nutshell, I wanted seamless integration between React and Django such that the build and test tools that ship with both technologies continue to work without any interference being caused by the presence of either technology. And additionally, I wanted both technologies to not require any special configuration in production. I believe that the method outlined in this article achieves these design goals, and it bears mentioning that as of this writing I’ve not seen this strategy described elsewhere on the Internet. I’m reasonably sure that all of the following are accomplished.:
- Seamless integration between React and Django.
- You can use Django for REST API, user authentications, site headers & footers, admin, and testing
- You can use React on any pages in your project of your choosing.
- All of the build and test tools for both Django and React will continue to work, with no special configuration required.
- You can include popular, complex tooling in your React stack such as Redux, React Router, Bootstrap, etcetera.
- All of the native optimizations in “npm run build” like page chunking will continue to work.
- You can manage all of your code in a single repository
Sample Output
Here’s an example page rendered using this integration methodology. Thanks to name spacing in React along with its quite-impressive build tool, getting React content to appear inside a Django-rendered page is as simple as including the css and js optimized build bundles, and including a div in the html body with an id value that matches that specified in your src/index.js file which in this case is, document.getElementById('reactjs-root')
. Note the following:
- the page header and footer are generated by Django
- the Django debug toolbar is present on the righthand sidebar
- the page itself requires authentication which is managed by Django
- the black interior region is React-created content
Furthermore, as you can see from the html source to the right, the React content is being rendered normally, with the optimized css and js bundles created by React’s npm run build
added to the head section of the DOM, and the standard React hook added to the body element.
To verify that the build chain actually works I’ve modified frontend/src/App.js, adding one image and one line of text. Here’s a link to an archived copy of the complete Django template-rendered html that’s summarized on the right side of the illustration below.
A Bit of Theory
Before we get into the specifics of the technical implementation it behooves us to highlight a couple of React’s architectural principals that weigh on our strategy. First, React handles all file system addressing relative to a project’s root folder, and thus, we can place the root folder anywhere in the file system and React’s build tools will work fine. This should already be apparent to you from your experience building standalone React apps, and this matters in our case because we need to place React’s build output inside of a special Django app that will serve all React content.
Second, a production React build consists entirely of static files, and thus, nearly all of your React content will be served by Django’s built-in django.contrib.staticfiles. We simply need to add some configuration settings to config/settings/base.py to enable staticfile to find the React build. I say nearly all because we’ll ignore React’s build/index.html file at run-time in favor of Django’s templating system, which leads us to the crux element of this integration strategy:
Key Concept
For any Django template-rendered page which we want to include React content we need to implement a Django view and template that adds React’s optimized css and js bundled entry points into the head of the DOM, and adds a div to the body element with id=”reactjs-root”.
Lastly and to that end, we need to understand a couple of superficial aspects of React’s build output (see illustration to the right) that is generated by the command, npm run build
or alternatively, yarn run build
. The structure of React’s build output is fixed and has some defining features such as the folder structures and the locations and names of the css and js entry point bundles which we will reference in a Django view later in this article.
Of particular importance to us is the output file build/asset-manifest.json because its contents describe the relative file paths of the optimized css and js bundles that the build script created, and we need to add links to these two files in the head of our Django template output.
Technical Implementation Strategy: Django + React Setup
At the risk of being repetitive I’ll kindly remind you that you can clone a fully-functioning repository of this implementation strategy, and that the code and copious documentation contained therein are really the best way to get up to speed on how what follows actually works.
In a blank Django project scaffolded with CookieCutter Django we’re going to do the following:
- Create a Django app named “frontend”. This app only needs three elements: apps.py, views.py, and a templates folder. The page links point to the actual source code for each element. The app will functionally replace React’s
index.html
for purposes of generating React content in the browser. - From the root of the “frontend” Django app, create a new React app using the standard command line,
npx create-react-app frontend
. You should immediately runnpm run build
to create an initial set of build output for testing purposes. Afterwards we’ll consolidate the React project contents into the root of the Django app “frontend” as per the screen shot to the left. We don’t do anything special to this scaffolding, which is the entire point of this strategy. - Add a few things to the bottom of config/settings/base.py which again, you can peruse in detail by following the link.
- Add a line to config/urls.py that points to our Django app “frontend”.
I additionally stripped down the contents of public/index.html to its bare essentials which, while not technically necessary, definitely helps to clarify what is really needed for this implementation. So just be aware that, if you clone my repository, you’ll see a quite stripped down version of what you’re accustomed to seeing when running the React dev server.
The screen shots below illustrate the relationships between the code objects that we’re either creating or referencing. Ultimately, what’s being doing in this integration strategy is laughably simple, once you understand it. Really, the only challenge to this entire strategy is that the work we’re doing is easily lost within the size and complexity of both Django and React. For your convenience I’m including links to each of the four files in the illustration.
Good luck with next steps on your project!! I hope you found this helpful. Contributors are welcome. My contact information is on my web site. Please help me improve this article by leaving a comment below. Thank you!
is this widely practiced? i cant find one project build like this not even a simple contact list
I can’t really speak for the Internet at large, but, you might take a look at this Django-React integration strategy for the Open edX software project, which is pretty widely followed – https://github.com/openedx/frontend-platform