Package: django-nextjs
Django Next.jsNext.js integration for Django projects.So you want to use both Django and Next.js in your project. There are two scenarios:You are starting a new project and you want to use Django as back-end and Next.js as front-end.
Django only serves API requests. All front-end code lives in Next.js and you don't write any Django template.In this scenario youdon't needthis package (although you can use it).
You simply start both Django and Next.js servers and point your public webserver to Next.js.You need both Django templates and Next.js at the same time and those pages should easily link to each other.
Maybe you have an existing Django project which has pages rendered by Django template
and want some new pages in Next.js.
Or you want to migrate your front-end to Next.js but since the project is large, you need to do it gradually.In this scenario,this package is for you!How does it work?From acomment on StackOverflow:Run 2 ports on the same server. One for django (public facing)
and one for Next.js (internal).
Let django handle all web requests.
For each request, query Next.js from django view to get HTML response.
Return that exact HTML response from django view.InstallationInstall the latest version from PyPI.pipinstalldjango-nextjsAdddjango_nextjs.apps.DjangoNextJSConfigtoINSTALLED_APPS.Set up Next.js URLs depending on your environment.Setup Next.js URLs (Development Environment)If you're serving your site under ASGI during development,
useDjango Channelsand
addNextJSProxyHttpConsumer,NextJSProxyWebsocketConsumertoasgi.pylike the following example.Note:We recommend using ASGI and Django Channels,
because it is required forfast refresh(hot module replacement) to work properly in Nextjs 12+.importosfromdjango.core.asgiimportget_asgi_applicationfromdjango.urlsimportre_path,pathos.environ.setdefault("DJANGO_SETTINGS_MODULE","myproject.settings")django_asgi_app=get_asgi_application()fromchannels.authimportAuthMiddlewareStackfromchannels.routingimportProtocolTypeRouter,URLRouterfromdjango_nextjs.proxyimportNextJSProxyHttpConsumer,NextJSProxyWebsocketConsumerfromdjango.confimportsettings# put your custom routes here if you needhttp_routes=[re_path(r"",django_asgi_app)]websocket_routers=[]ifsettings.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)),# ...})Otherwise (if serving under WSGI during development), add the following to the beginning ofurls.py:path("",include("django_nextjs.urls"))Warning:If you are serving under ASGI, do NOT add this
to yoururls.py. It may cause deadlocks.Setup Next.js URLs (Production Environment)In production, use a reverse proxy like Nginx or Caddy:URLAction/_next/static/...ServeNEXTJS_PATH/.next/staticdirectory/_next/...Proxy tohttp://localhost:3000/next/...ServeNEXTJS_PATH/public/nextdirectoryPassx-real-ipheader when proxying/_next/. Example config for Nginx:location /_next/static/ {
    alias NEXTJS_PATH/.next/static/;
    expires max;
    add_header Cache-Control "public";
}
location /_next/ {
    proxy_set_header  x-real-ip $remote_addr;
    proxy_pass  http://127.0.0.1:3000;
}
location /next/ {
    alias NEXTJS_PATH/public/next/;
    expires max;
    add_header Cache-Control "public";
}UsageStart Next.js server:# Development:$npmrundev# Production:$npmrunbuild
$npmrunstartDevelop your pages in Next.js.
Write a django URL and an async view for each page like this:fromdjango.httpimportHttpResponsefromdjango_nextjs.renderimportrender_nextjs_pageasyncdefjobs(request):returnawaitrender_nextjs_page(request)Customizing the HTML ResponseYou can modify the HTML code that Next.js returns in your Django code.Avoiding duplicate code for the navbar and footer is a common use case
for this if you are using both Next.js and Django templates.
Without it, you would have to write and maintain two separate versions
of your navbar and footer (a Django template version and a Next.js version).
However, you can simply create a Django template for your navbar and insert its code
at the beginning of<body>tag returned from Next.js.To enable this feature, you need to customize the document and root layout
in Next.js and make the following adjustments:Addid="__django_nextjs_body"as the first attribute of<body>element.Add<div id="__django_nextjs_body_begin" />as the first element inside<body>.Add<div id="__django_nextjs_body_end" />as the last element inside<body>.NOTE: Currently HTML customization is not working withapp router(Next.js 13+).Readthis docand customize your Next.js document:// pages/_document.jsx (or .tsx)
...
<body id="__django_nextjs_body">
  <div id="__django_nextjs_body_begin" />
  <Main />
  <NextScript />
  <div id="__django_nextjs_body_end" />
</body>
...Write a django template that extendsdjango_nextjs/document_base.html:{%extends"django_nextjs/document_base.html"%}{%blockhead%}<!-- ... the content you want to place at the beginning of "head" tag ... -->{{block.super}}<!-- ... the content you want to place at the end of "head" tag ... -->{%endblock%}{%blockbody%}... the content you want to place at the beginning of "body" tag ...... e.g. include the navbar template ...{{block.super}}... the content you want to place at the end of "body" tag ...... e.g. include the footer template ...{%endblock%}Pass the template name torender_nextjs_page:asyncdefjobs(request):returnawaitrender_nextjs_page(request,"path/to/template.html")NotesIf you want to add a file topublicdirectory of Next.js,
that file should be inpublic/nextsubdirectory to work correctly.If you're using django channels, make sure all your middlewares areasync-capable.To avoid "Too many redirects" error, you may need to addAPPEND_SLASH = Falsein your Django project'ssettings.py. Also, do not add/at the end of nextjs paths inurls.py.This package does not provide a solution for passing data from Django to Next.js. The Django Rest Framework, GraphQL, or similar solutions should still be used.The Next.js server will not be run by this package. You will need to run it yourself.SettingsDefault settings:NEXTJS_SETTINGS={"nextjs_server_url":"http://127.0.0.1:3000",}nextjs_server_urlThe URL of Next.js server (started bynpm run devornpm run start)DevelopmentInstall development dependencies in your virtualenv withpip install -e '.[dev]'Install pre-commit hooks usingpre-commit install.Referenceshttps://github.com/yourlabs/djnextcomment on StackOverflowLicenseMIT