{"id":24740075,"url":"https://github.com/querateam/django-nextjs","last_synced_at":"2025-05-15T04:04:22.482Z","repository":{"id":37665827,"uuid":"453717752","full_name":"QueraTeam/django-nextjs","owner":"QueraTeam","description":"Integrate Next.js into your Django project","archived":false,"fork":false,"pushed_at":"2025-05-11T16:16:41.000Z","size":520,"stargazers_count":378,"open_issues_count":1,"forks_count":21,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-05-15T04:03:30.036Z","etag":null,"topics":["django","integration","nextjs"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/QueraTeam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-01-30T15:25:25.000Z","updated_at":"2025-05-02T20:43:24.000Z","dependencies_parsed_at":"2024-06-18T21:32:48.289Z","dependency_job_id":"821432ef-59cd-4bb2-b3f6-86d4991de48d","html_url":"https://github.com/QueraTeam/django-nextjs","commit_stats":{"total_commits":61,"total_committers":5,"mean_commits":12.2,"dds":0.4426229508196722,"last_synced_commit":"bd6e94bcaa1064e3b32bb73250392052743d9bde"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueraTeam%2Fdjango-nextjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueraTeam%2Fdjango-nextjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueraTeam%2Fdjango-nextjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueraTeam%2Fdjango-nextjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QueraTeam","download_url":"https://codeload.github.com/QueraTeam/django-nextjs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270641,"owners_count":22042858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","integration","nextjs"],"created_at":"2025-01-27T23:20:36.336Z","updated_at":"2025-05-15T04:04:22.413Z","avatar_url":"https://github.com/QueraTeam.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Django-Next.js\n\n[![PyPI version](https://img.shields.io/pypi/v/django-nextjs.svg)](https://pypi.python.org/pypi/django-nextjs/)\n[![Tests status](https://github.com/QueraTeam/django-nextjs/workflows/tests/badge.svg)](https://github.com/QueraTeam/django-nextjs/actions)\n[![License: MIT](https://img.shields.io/github/license/QueraTeam/django-nextjs.svg)](https://github.com/QueraTeam/django-nextjs/blob/master/LICENSE)\n[![Code style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nIntegrate Next.js into your Django project,\nallowing Django and Next.js pages to work together seamlessly.\n\n## Is this package right for you?\n\ndjango-nextjs is designed for projects\nthat need both Django pages (usually rendered by Django templates) and Next.js pages. Some scenarios:\n\n- You want to add some Next.js pages to an existing Django project.\n- You want to migrate your frontend to Next.js, but since the project is large, you want to do it gradually.\n\nIf this sounds like you, **this package is the perfect fit**. ✅\n\nHowever, if you’re starting a new project and intend to use Django purely as an API backend with Next.js as a standalone frontend, you **don’t need** this package.\nSimply run both servers and configure your public web server to point to Next.js for a straightforward setup.\n\n## How does it work?\n\nWhen a user opens a page, django receives the initial request, queries the Next.js server for the HTML response, and returns it to the user.\nAfter opening a Next.js page, the user can navigate to other Next.js pages without any additional requests to Django (the Next.js server handles the routing).\n\nThis is how it looks like in production:\n\n![How it works in production](.github/assets/how-it-works-production.webp)\n\nIn development, to simplify the setup and remove the need to a reverse proxy like Nginx, Django also acts as the reverse proxy for Next.js client-side requests.\n\n## Getting Started\n\n- Install the latest version from PyPI.\n\n  ```shell\n  pip install django-nextjs\n  ```\n\n- Add `django_nextjs.apps.DjangoNextJSConfig` to `INSTALLED_APPS`.\n\n- Set up Next.js URLs depending on your environment.\n\n## Setup Next.js URLs (Development Environment)\n\nIf you're serving your site under ASGI during development,\nuse [Django Channels](https://channels.readthedocs.io/en/stable/) and\nadd `NextJSProxyHttpConsumer`, `NextJSProxyWebsocketConsumer` to `asgi.py` like the following example.\n\n**Note:** We recommend using ASGI and Django Channels,\nbecause it is required for [fast refresh](https://nextjs.org/docs/architecture/fast-refresh) (hot module replacement) to work properly in Nextjs 12+.\n\n```python\nimport os\n\nfrom django.core.asgi import get_asgi_application\nfrom django.urls import re_path, path\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"myproject.settings\")\ndjango_asgi_app = get_asgi_application()\n\nfrom channels.auth import AuthMiddlewareStack\nfrom channels.routing import ProtocolTypeRouter, URLRouter\nfrom django_nextjs.proxy import NextJSProxyHttpConsumer, NextJSProxyWebsocketConsumer\n\nfrom django.conf import settings\n\n# put your custom routes here if you need\nhttp_routes = [re_path(r\"\", django_asgi_app)]\nwebsocket_routers = []\n\nif settings.DEBUG:\n    http_routes.insert(0, re_path(r\"^(?:_next|__next|next).*\", NextJSProxyHttpConsumer.as_asgi()))\n    websocket_routers.insert(0, path(\"_next/webpack-hmr\", NextJSProxyWebsocketConsumer.as_asgi()))\n\n\napplication = ProtocolTypeRouter(\n    {\n        # Django's ASGI application to handle traditional HTTP and websocket requests.\n        \"http\": URLRouter(http_routes),\n        \"websocket\": AuthMiddlewareStack(URLRouter(websocket_routers)),\n        # ...\n    }\n)\n```\n\nOtherwise (if serving under WSGI during development), add the following to the beginning of `urls.py`:\n\n```python\npath(\"\", include(\"django_nextjs.urls\"))\n```\n\n**Warning:** If you are serving under ASGI, do NOT add this\nto your `urls.py`. It may cause deadlocks.\n\n## Setup Next.js URLs (Production Environment)\n\nIn production, use a reverse proxy like Nginx or Caddy:\n\n| URL                 | Action                                     |\n| ------------------- | ------------------------------------------ |\n| `/_next/static/...` | Serve `NEXTJS_PATH/.next/static` directory |\n| `/_next/...`        | Proxy to `http://localhost:3000`           |\n| `/next/...`         | Serve `NEXTJS_PATH/public/next` directory  |\n\nExample config for Nginx:\n\n```conf\nlocation /_next/static/ {\n    alias NEXTJS_PATH/.next/static/;\n    expires max;\n    add_header Cache-Control \"public\";\n}\nlocation /_next/ {\n    proxy_pass  http://127.0.0.1:3000;\n    proxy_set_header Host $http_host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header X-Forwarded-Proto $scheme;\n}\nlocation /next/ {\n    alias NEXTJS_PATH/public/next/;\n    expires max;\n    add_header Cache-Control \"public\";\n}\n```\n\n## Usage\n\nStart Next.js server:\n\n```shell\n# Development:\n$ npm run dev\n\n# Production:\n$ npm run build\n$ npm run start\n```\n\nStart by developing your pages in Next.js, Then define a Django URL for each Next.js page. Here's an example of how you can do this:\n\n```python\nfrom django_nextjs.views import nextjs_page\n\nurlpatterns = [\n    path(\"/nextjs/page\", nextjs_page(), name=\"nextjs_page\"),\n]\n```\n\nEven though it's not recommended, sometimes you might need to add some custom steps before showing a Next.js page in Django. However, **we advise moving this logic to Next.js to ensure it's applied even during client-side navigation**. If you find yourself in this situation, you can create an asynchronous view for each page as demonstrated below:\n\n```python\nfrom django_nextjs.render import render_nextjs_page\n\nasync def jobs(request):\n    # Your custom logic\n    return await render_nextjs_page(request)\n```\n\n## Customizing the HTML Response\n\nYou can modify the HTML code that Next.js returns in your Django code.\n\nAvoiding duplicate code for the navbar and footer is a common use case\nfor this if you are using both Next.js and Django templates.\nWithout it, you would have to write and maintain two separate versions\nof your navbar and footer (a Django template version and a Next.js version).\nHowever, you can simply create a Django template for your navbar and insert its code\nat the beginning of `\u003cbody\u003e` tag returned from Next.js.\n\nTo enable this feature, you need to customize the document and root layout\nin Next.js and make the following adjustments:\n\n- Add `id=\"__django_nextjs_body\"` as the first attribute of `\u003cbody\u003e` element.\n- Add `\u003cdiv id=\"__django_nextjs_body_begin\" /\u003e` as the first element inside `\u003cbody\u003e`.\n- Add `\u003cdiv id=\"__django_nextjs_body_end\" /\u003e` as the last element inside `\u003cbody\u003e`.\n\nNOTE: Currently HTML customization is not working with [app router](https://nextjs.org/docs/app) (Next.js 13+).\n\nRead\n[this doc](https://nextjs.org/docs/pages/building-your-application/routing/custom-document)\nand customize your Next.js document:\n\n```jsx\n// pages/_document.jsx (or .tsx)\n...\n\u003cbody id=\"__django_nextjs_body\"\u003e\n  \u003cdiv id=\"__django_nextjs_body_begin\" /\u003e\n  \u003cMain /\u003e\n  \u003cNextScript /\u003e\n  \u003cdiv id=\"__django_nextjs_body_end\" /\u003e\n\u003c/body\u003e\n...\n```\n\n\u003c!-- If you are using Next.js 13+, you also need to\n[customize the root layout](https://nextjs.org/docs/app/api-reference/file-conventions/layout)\nin `app` directory:\n\n```jsx\n// app/layout.jsx (or .tsx)\n...\n\u003cbody id=\"__django_nextjs_body\" className={inter.className}\u003e\n  \u003cdiv id=\"__django_nextjs_body_begin\" /\u003e\n  {children}\n  \u003cdiv id=\"__django_nextjs_body_end\" /\u003e\n\u003c/body\u003e\n...\n``` --\u003e\n\nWrite a Django template that extends `django_nextjs/document_base.html`:\n\n```django\n{% extends \"django_nextjs/document_base.html\" %}\n\n\n{% block head %}\n  \u003c!-- ... the content you want to place at the beginning of \"head\" tag ... --\u003e\n  {{ block.super }}\n  \u003c!-- ... the content you want to place at the end of \"head\" tag ... --\u003e\n{% endblock %}\n\n\n{% block body %}\n  ... the content you want to place at the beginning of \"body\" tag ...\n  ... e.g. include the navbar template ...\n  {{ block.super }}\n  ... the content you want to place at the end of \"body\" tag ...\n  ... e.g. include the footer template ...\n{% endblock %}\n```\n\nPass the template name to `nextjs_page` or `render_nextjs_page`:\n\n```python\nfrom django_nextjs.render import render_nextjs_page\nfrom django_nextjs.views import nextjs_page\n\nasync def jobs(request):\n    return await render_nextjs_page(request, template_name=\"path/to/template.html\")\n\nurlpatterns = [\n    path(\"/nextjs/page\", nextjs_page(template_name=\"path/to/template.html\"), name=\"nextjs_page\"),\n    path(\"/jobs\", jobs, name=\"jobs_page\")\n]\n\n```\n\n## Notes\n\n- If you want to add a file to `public` directory of Next.js,\n  that file should be in `public/next` subdirectory to work correctly.\n- If you're using Django channels, make sure all your middlewares are\n  [async-capable](https://docs.djangoproject.com/en/dev/topics/http/middleware/#asynchronous-support).\n- To avoid \"Too many redirects\" error, you may need to add `APPEND_SLASH = False` in your Django project's `settings.py`. Also, do not add `/` at the end of nextjs paths in `urls.py`.\n- 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.\n- The Next.js server will not be run by this package. You will need to run it yourself.\n\n## Settings\n\nDefault settings:\n\n```python\nNEXTJS_SETTINGS = {\n    \"nextjs_server_url\": \"http://127.0.0.1:3000\",\n    \"ensure_csrf_token\": True,\n}\n```\n\n### `nextjs_server_url`\n\nThe URL of Next.js server (started by `npm run dev` or `npm run start`)\n\n### `ensure_csrf_token`\n\nIf the user does not have a CSRF token, ensure that one is generated and included in the initial request to the Next.js server by calling Django's `django.middleware.csrf.get_token`. If `django.middleware.csrf.CsrfViewMiddleware` is installed, the initial response will include a `Set-Cookie` header to persist the CSRF token value on the client. This behavior is enabled by default.\n\n**When you need `ensure_csrf_token`?**\n\nYou may need to issue GraphQL POST requests to fetch data in Next.js `getServerSideProps`. If this is the user's first request, there will be no CSRF cookie, causing the request to fail since GraphQL uses POST even for data fetching.\nIn this case this option solves the issue,\nand as long as `getServerSideProps` functions are side-effect free (i.e., they don't use HTTP unsafe methods or GraphQL mutations), it should be fine from a security perspective. Read more [here](https://docs.djangoproject.com/en/3.2/ref/csrf/#is-posting-an-arbitrary-csrf-token-pair-cookie-and-post-data-a-vulnerability).\n\n## Contributing\n\nTo start development:\n\n- Install development dependencies in your virtualenv with `pip install -e '.[dev]'`\n- Install pre-commit hooks using `pre-commit install`.\n\nLove django-next.js? 🌟 Star us on GitHub to help the project grow!\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquerateam%2Fdjango-nextjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquerateam%2Fdjango-nextjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquerateam%2Fdjango-nextjs/lists"}