We are going to combine Django and Next.js servers, use Django to accept web requests and use Next.js as an internal service that generates the HTML.
Sources:
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.
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.
Required version
- Django 4.0.0
- django-nextjs 2.4.0
- channels 3.0.4
git clone [email protected]:ycpranchu/django-nextjs-build.git
cd django-nextjs-build
pip install -r requirements.txt
Django project name django-nextjs-blog
django-admin startproject 'django-nextjs-blog'
Django app name django_app
cd 'django-nextjs-blog'
python manage.py startapp 'django_app'
md static
md templates
Nextjs project name nextjs_app
npx create-next-app
npm run dev
The Next.js is up on port 3000.
- Add apps and requirements to
INSTALLED_APPS
.
INSTALLED_APPS = [
"django_app",
"channels",
"nextjs_app",
...
]
- Set the debug mode and allowed hosts.
DEBUG = True
ALLOWED_HOSTS = ['*']
- Set the
templates
directory path.
import os
TEMPLATES = [
{
...
"DIRS": [os.path.join(BASE_DIR, "templates")],
...
},
]
- Use ASGI instead of WSGI.
# WSGI_APPLICATION = "django_nextjs_blog.wsgi.application"
ASGI_APPLICATION = "django_nextjs_blog.asgi.application"
- Set the time zone.
LANGUAGE_CODE = "zh-hant"
TIME_ZONE = "UTC"
- Set the
static
directory path.
STATIC_URL = "static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
- Initialized the database.
python manage.py makemigrations
python manage.py migrate
Include the django-nextjs
URLs inside project urls.py
# django_nextjs_blog/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("django_app.urls")),
]
Set Django as ASGI server.
import os
from django.core.asgi import get_asgi_application
from django.urls import re_path, path
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_nextjs_blog.settings")
django_asgi_app = get_asgi_application()
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django_nextjs.proxy import NextJSProxyHttpConsumer, NextJSProxyWebsocketConsumer
from django.conf import settings
# put your custom routes here if you need
http_routes = [re_path(r"", django_asgi_app)]
websocket_routers = []
if settings.DEBUG:
http_routes.insert(0, re_path(r"^(?:_next|__next|next).*", NextJSProxyHttpConsumer.as_asgi()))
websocket_routers.insert(0, path("_next/webpack-hmr", NextJSProxyWebsocketConsumer.as_asgi()))
application = ProtocolTypeRouter(
{
# Django's ASGI application to handle traditional HTTP and websocket requests.
"http": URLRouter(http_routes),
"websocket": AuthMiddlewareStack(URLRouter(websocket_routers)),
# ...
}
)
from django.http import HttpResponse
from django_nextjs.render import render_nextjs_page
async def index(request):
return await render_nextjs_page(request)
create urls.py
under app's folder
# django_app/urls.py
from django.urls import path
from .views import index
urlpatterns = [
path("", index, name="index"),
]
Nextjs frontend
# terminal_1
npm run dev
Django server
# terminal_2
python manage.py runserver
Now you can see Nextjs
running on Django server
port 8000.