Skip to content

Commit 34ad5f8

Browse files
authored
Merge pull request #2 from django-cms/feat/extensive-readme
feat: add a basic outline
2 parents 50070dd + 70ecc9e commit 34ad5f8

File tree

1 file changed

+126
-90
lines changed

1 file changed

+126
-90
lines changed

README.rst

Lines changed: 126 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,171 @@
1-
|pythonapp|
1+
Making React a First-Class Citizen in Django CMS with React Router Integration
2+
===============================================================================
23

3-
#####################
4-
django CMS quickstart
5-
#####################
4+
Introduction
5+
------------
66

7-
- A dockerised django CMS project intended to be run locally in Docker on your own machine or on a Docker-based cloud, such as `Divio <https://www.divio.com/>`_
8-
- This version uses Python 3.11 and the most up-to-date versions of Django 4.2, and django CMS 4.1.0
9-
- This project is endorsed by the `django CMS Association <https://www.django-cms.org/en/about-us/>`_. That means that it is officially accepted by the dCA as being in line with our roadmap vision and development/plugin policy. Join us on `Slack <https://www.django-cms.org/slack/>`_ for more information or questions.
10-
- The documentation for django CMS can be found here: https://docs.django-cms.org/
7+
Django CMS is a powerful content management system that excels at structured, editorial content.
8+
However, modern frontend experiences often demand the flexibility and interactivity of React.
119

12-
Installation
13-
############
10+
In this post, we'll walk through how React — along with React Router — can be integrated as
11+
first-class citizens in a Django CMS project, so that your editors and frontend engineers
12+
can both thrive.
1413

15-
Requirements
16-
============
14+
Why Integrate React with Django CMS
15+
-----------------------------------
1716

18-
You need to have Docker installed on your system to run this project.
17+
- Django CMS provides content structure, versioning, and editorial workflows.
18+
- React enables interactive, dynamic UIs with modern developer ergonomics.
19+
- Common use cases:
1920

20-
- `Install Docker <https://docs.docker.com/engine/install/>`_ here.
21-
- If you have not used docker in the past, please read this
22-
`introduction on docker <https://docs.docker.com/get-started/>`_ here.
21+
- Embedding a dashboard or widget inside CMS-managed pages.
22+
- Creating fully dynamic web apps that live at certain CMS-defined routes.
23+
- Building reusable React-based plugins inside Django CMS placeholders.
2324

24-
Local Setup
25-
===========
25+
Approach Overview
26+
-----------------
2627

27-
.. inclusion-marker-do-not-remove
28+
There are two major strategies:
2829

29-
.. code-block:: bash
30+
- **SPA-in-CMS:** Let Django CMS render the base HTML layout and inject React into a placeholder.
31+
- **CMS-in-SPA:** Use Django CMS as a headless backend and build everything with React.
3032

31-
git clone git@github.com:django-cms/django-cms-quickstart.git
32-
cd django-cms-quickstart
33-
docker compose build web
34-
docker compose up -d database_default
35-
docker compose run --rm web python manage.py migrate
36-
docker compose run --rm web python manage.py createsuperuser
37-
docker compose up -d
33+
In this guide, we'll use the **SPA-in-CMS** approach, where React is bootstrapped inside
34+
a Django CMS placeholder and React Router manages the internal routing.
3835

39-
Then open http://django-cms-quickstart.127.0.0.1.nip.io:8000 (or just http://127.0.0.1:8000) in your browser.
36+
Project Setup
37+
-------------
4038

41-
You can stop the server with ``docker compose stop`` without destroying the containers and restart it with
42-
``docker compose start``.
39+
1. Setup Django CMS (you can use `djangocms-installer` or your custom setup).
40+
2. Create a React app:
4341

44-
With ``docker compose down`` the containers are deleted, but the database content is still preserved in the named
45-
volume ``django-cms-quickstart_postgres-data`` and the media files are stored in the file system in ``data/media``.
46-
Then you can update the project e. g. by changing the requirements and settings. Finally you can rebuild the web image
47-
and start the server again:
42+
- With `create-react-app`, Vite, or Webpack.
43+
3. Integrate using either:
4844

49-
.. code-block:: bash
45+
- `django-webpack-loader` (Webpack),
46+
- or `django-vite`.
5047

51-
docker compose build web
52-
docker compose up -d
48+
Serving React from Django CMS
49+
-----------------------------
5350

51+
- Create a Django CMS plugin that renders a `<div id="react-root"></div>` in a placeholder.
52+
- This div acts as the mounting point for the React app.
53+
- Your CMS template might look like:
5454

55-
Note: Since Compose V2, ``docker-compose`` is now included inside docker. For more information, checkout the
56-
`Compose V2 <https://docs.docker.com/compose/cli-command/>`_ Documentation.
55+
.. code-block:: html
5756

58-
.. inclusion-end-marker-do-not-remove
57+
{% load render_placeholder %}
58+
<html>
59+
<body>
60+
{% render_placeholder "main" %}
61+
<script src="{% render_bundle 'main' %}"></script>
62+
</body>
63+
</html>
5964

60-
Customising the project
61-
#######################
65+
- You can also pass page or context data from the backend to React via `data-*` attributes or global JS variables.
6266

63-
This project is ready-to-go without making any changes at all, but also gives you some options.
67+
React Router Configuration
68+
--------------------------
6469

65-
As-is, it will include a number of useful django CMS plugins and Bootstrap 4 for the frontend. You don't have to use
66-
these; they're optional. If you don't want to use them, read through the ``settings.py`` and ``requirements.txt`` files
67-
to see sections that can be removed - in each case, the section is noted with a comment containing the word 'optional'.
70+
- Wrap your React app with `<BrowserRouter>` or `<HashRouter>`.
71+
- Configure a base path if the React app lives under a CMS-defined URL like `/app/`.
72+
- Example:
6873

69-
Options are also available for using Postgres/MySQL, uWSGI/Gunicorn/Guvicorn, etc.
74+
.. code-block:: jsx
7075
71-
Updating requirements
72-
=====================
76+
import { BrowserRouter, Routes, Route } from 'react-router-dom';
7377
74-
The project uses a django best practise two step approach, freezing all dependencies with pip-tools. Here is how to update requirements:
78+
const App = () => (
79+
<BrowserRouter basename="/app">
80+
<Routes>
81+
<Route path="/" element={<Home />} />
82+
<Route path="profile" element={<Profile />} />
83+
</Routes>
84+
</BrowserRouter>
85+
);
7586
76-
1. Change ``requirements.in`` according to your needs. There is no need to pin the package versions here unless you have a good reason (i.e. known incompatibilities)
77-
2. Run ``docker compose run --rm web pip-compile requirements.in >> requirements.txt``
78-
3. ``requirements.txt`` should now have changed
79-
4. Rebuild the container ``docker compose build web`` and restart ``docker compose up -d``
87+
Handling Routing Conflicts
88+
--------------------------
8089

81-
Features
82-
########
90+
- Prevent Django from trying to resolve React's client-side routes.
91+
- Add a CMS page with the URL `/app/` and insert your React plugin there.
92+
- Any sub-routes like `/app/profile` will be handled by React Router.
8393

84-
Static Files with Whitenoise
85-
============================
94+
Advanced Considerations
95+
-----------------------
8696

87-
- This quickstart demo has a cloud-ready static files setup via django-whitenoise.
88-
- In the containerized cloud the application is not served by a web server like nginx but directly through uwsgi. django-whitenoise is the glue that's needed to serve static files in your application directly through uwsgi.
89-
- See the django-whitenoise settings in settings.py and the ``quickstart/templates/whitenoise-static-files-demo.html`` demo page template that serves a static file.
97+
- **SEO/SSR**: React apps are client-side rendered; for SEO-heavy use cases, consider SSR or pre-rendering.
98+
- **i18n**: Pass `language_code` from Django CMS to React, and use libraries like `react-i18next`.
99+
- **Context sync**: Provide CMS context to React via props, global config, or context providers.
90100

91-
Env variables
92-
=============
101+
Example Configuration Snippets
102+
------------------------------
93103

94-
- By default, Docker injects the env vars defined in ``.env-local`` into the quickstart project.
95-
- If you want to access the PostgreSQL database from the host system, set ``DB_PORT`` to the desired port number.
96-
5432 is the standard port number. If you run PosgreSQL on your host system, you may want to set another port number.
97-
If this variable is empty (the default), the PosgreSQL instance in the container is only reachable within docker, but
98-
not from outside.
104+
- **Webpack:**
99105

100-
Contribution
101-
############
106+
.. code-block:: js
102107
103-
Here is the official django CMS repository:
104-
`https://github.com/django-cms/django-cms-quickstart/ <https://github.com/django-cms/django-cms-quickstart/>`_.
108+
// webpack.config.js
109+
output: {
110+
publicPath: '/static/webpack_bundles/',
111+
}
105112
113+
- **settings.py:**
106114

107-
Deployment
108-
##########
115+
.. code-block:: python
109116
110-
Note that this is just a demo project to get you started. It is designed to be run locally through docker. If you want a full production ready site with all the bells
111-
and whistles we recommend you have a look at https://github.com/django-cms/djangocms-template instead.
117+
INSTALLED_APPS += ['webpack_loader']
118+
WEBPACK_LOADER = {
119+
'DEFAULT': {
120+
'BUNDLE_DIR_NAME': 'webpack_bundles/',
121+
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
122+
}
123+
}
112124
113-
Some deployment hints:
125+
- **CMS Template:**
114126

115-
- To deploy this project in testing mode (recommended) set the environment variable ``DEBUG`` to ``True`` in your hosting environment.
116-
- Be aware that if ``DEBUG`` is false, django requires you to whitelist the domain. Set the env var ``DOMAIN`` to the host, i.e. ``www.domain.com`` or ``*.domain.com``.
117-
- You can set the env var ``DEFAULT_STORAGE_DSN`` to something meaningful (i.e. for s3 file storage)
127+
.. code-block:: html
118128

119-
Deployment Commands
120-
===================
129+
<div id="react-root"></div>
121130

122-
Configure your hosting environment to run the following commands on every deployment:
131+
- **React App Entry:**
123132

124-
- ``./manage.py migrate``
133+
.. code-block:: js
125134
135+
import ReactDOM from 'react-dom/client';
136+
import App from './App';
126137
127-
Divio Deployment
128-
================
138+
const root = document.getElementById('react-root');
139+
ReactDOM.createRoot(root).render(<App />);
129140
130-
divio.com is a cloud hosting platform optimized for django web applications. It's the quickest way to deploy this
131-
project. Here is a `video tutorial <https://www.youtube.com/watch?v=O2g5Wfoyp7Q>`_ and a
132-
`description of the deployment steps <https://github.com/django-cms/djangocms-template/blob/mco-standalone/docs/deployment-divio.md#divio-project-setup>`_ that are mostly applicable for this quickstart project.
141+
Deployment Tips
142+
---------------
133143

144+
- Run `npm run build` (or Vite equivalent).
145+
- Collect static files via `collectstatic`.
146+
- Optionally serve assets via CDN.
147+
- Avoid client/server routing conflicts by keeping React confined under predictable base paths.
134148

135-
.. |pythonapp| image:: https://github.com/django-cms/django-cms-quickstart/workflows/Python%20application/badge.svg?branch=support/cms-4.1.x
149+
Conclusion
150+
----------
151+
152+
By carefully integrating React into Django CMS via placeholders and using React Router for
153+
client-side navigation, you can build rich, dynamic UIs within an editorially friendly platform.
154+
155+
This hybrid setup lets you enjoy the best of both worlds — clean backend content structure
156+
and dynamic, reactive frontends.
157+
158+
Optional Appendix
159+
-----------------
160+
161+
- Example repo link (if any)
162+
- Troubleshooting:
163+
164+
- Missing static files?
165+
- Routing conflicts?
166+
- React Router not picking up URL paths?
167+
168+
- Future ideas:
169+
170+
- Use of Next.js or RSC (React Server Components).
171+
- CMS-driven metadata injection for SSR.

0 commit comments

Comments
 (0)