Django + Next.js The Easy Way
Tags: django, nextjs, python, javascript
Published: 2022-03-25 18:57:55

## Introduction

After reading this article, you can create or enhance your projects using the many convenient features of Next.js and Django.

Using React instead of a Django template to create your frontend gives you access to many existing modern tools without the SEO issues of a SPA (Single Page Application) thanks to Next.js SSR capability.

You’ll also learn how to add Next.js to your **existing Django project** without any hassle, using [django-nextjs](https://github.com/QueraTeam/django-nextjs).

### Django

Django is a popular and fully featured server-side web framework, written in Python.

### Next.js

Next.js is an open-source development framework built on top of Node.js, enabling React-based web applications functionalities such as server-side rendering and generating static websites.

## How We Integrated Django + Next.js

There are several approaches to using these two frameworks together, but we are using one of them.

We are going to run Django and Next.js servers at the same time, use **Django to accept web requests** and use **Next.js as an internal service** that generates the HTML.

Accordingly, Django handles web requests, and for each request, Next.js is called inside the Django view to get the HTML response.

This is perfect **if you already have a Django project**, and you don’t want to change anything and **just start using Next.js** with it!

**You can use this approach even if you are starting a new project** because you’ll be able to use more Django features (e.g. sessions).

## Architecture

You can use `django-nextjs` in both development and production environments easily:

### Development Environment

When you run the project with `./manage.py runserver`, you are using Django as a proxy for all the requests between you and Next.js.

![Development — django-nextjs](https://cdn-images-1.medium.com/max/2000/1*qsH_G4uOlzancerUQ3Z3VA.png)

### Production Environment

In production, you should proxy some Next.js requests (requests that require no Django manipulation) through your webserver to reduce unnecessary loads on the Django server. For more information, check out our [docs](https://github.com/QueraTeam/django-nextjs).

![Production — django-nextjs](https://cdn-images-1.medium.com/max/2000/1*2f0gUgNgjTtqyNEAtLtW3A.png)

## Let’s Code!

Before we start, if you are already using django-channels in your project, or you need HMR (hot module replacement) you should set up `django-nextjs` with `django-channels`. Read it from our [docs](https://github.com/QueraTeam/django-nextjs).

### Nextjs

* Create Next.js project inside your Django project (or anywhere you want):
    ```
    npx create-next-app
    ```
* Run the Next.js development server:
    ```
    npm run dev
    ```
The Next.js is up on port 3000, and in the / path shows the default welcome page:

![The Next.js welcome page on port 3000](https://cdn-images-1.medium.com/max/2070/1*Resc3lH1bIGabvkBWTeC7A.png)

Now our goal is to receive this page from a Django-powered server!

### Django

* Install the `django-nextjs` package, inside the same python environment, your Django project uses:
    ```
    pip install django-nextjs
    ```
* Add `django_nextjs` to `INSTALLED_APPS` in Django settings:
    ```py
    INSTALLED_APPS = [
        # ...
        "django_nextjs",
    ]
    ```
* Include the django-nextjs URLs inside your root `urls.py` file:
    ```py
    # myproject/urls.py

    from django.urls import include, path

    urlpatterns = [
        # ...
        path("", include("myapp.urls")),
        path("", include("django_nextjs.urls")),
    ]
    ```
* Write the next.js page view inside your app:
    ```py
    # myapp/views.py

    from django_nextjs.render import render_nextjs_page_sync

    def index(request):
        return render_nextjs_page_sync(request)
    ```
* Add the new view to `urls.py`:
    ```py
    # myapp/urls.py

    from django.urls import path
    from .views import index

    urlpatterns = [
        path("", index, name="index"),
    ]
    ```
* Run the Django development server:
    ```
    ./manage.py runserver
    ```
Now we can see the Next.js page through the Django:

![The Next.js welcome page from the Django development server on port 8000](https://cdn-images-1.medium.com/max/2070/1*DzvAyPrfbvgCdAU0qHU5zw.png)

### Notes

* The URL defined in Django should match with the related Next.js page you want to show. In other words, you should get the same result when you open localhost:8000/path and localhost:3000/path.

* If you need to show a Next.js page in another path in Django, feel free to use [Next.js Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites).

* You can extend Next.js pages in the Django layer if you need. Read more in django-nextjs [docs](https://github.com/QueraTeam/django-nextjs).

## What’s Next

You can find django-nextjs on [PyPI](https://pypi.org/project/django-nextjs/) and [GitHub](https://github.com/QueraTeam/django-nextjs):

* [https://pypi.org/project/django-nextjs/](https://pypi.org/project/django-nextjs/)

* [https://github.com/QueraTeam/django-nextjs](https://github.com/QueraTeam/django-nextjs)

This project has been made with ❤️ and used [on production](http://quera.org/magnet/jobs) for a year now. It’s pretty stable.

Check out our other projects [on GitHub](https://github.com/QueraTeam).
We appreciate your support.

## References

* [https://github.com/yourlabs/djnext](https://github.com/yourlabs/djnext)

* [https://stackoverflow.com/questions/54252943/is-there-a-way-to-integrate-django-with-next-js#comment110078700_54252943](https://stackoverflow.com/questions/54252943/is-there-a-way-to-integrate-django-with-next-js#comment110078700_54252943)