<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Danial Keimasi</title>
    <description>The latest articles on DEV Community by Danial Keimasi (@danialkeimasi).</description>
    <link>https://dev.to/danialkeimasi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F668134%2Fc607e693-b49a-450e-95f7-f4d4c7ea4915.jpeg</url>
      <title>DEV Community: Danial Keimasi</title>
      <link>https://dev.to/danialkeimasi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danialkeimasi"/>
    <language>en</language>
    <item>
      <title>Django + Next.js The Easy Way</title>
      <dc:creator>Danial Keimasi</dc:creator>
      <pubDate>Fri, 25 Mar 2022 18:57:55 +0000</pubDate>
      <link>https://dev.to/danialkeimasi/django-nextjs-the-easy-way-5a0h</link>
      <guid>https://dev.to/danialkeimasi/django-nextjs-the-easy-way-5a0h</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;After reading this article, you can create or enhance your projects using the many convenient features of Next.js and Django.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;You’ll also learn how to add Next.js to your &lt;strong&gt;existing Django project&lt;/strong&gt; without any hassle, using &lt;a href="https://github.com/QueraTeam/django-nextjs" rel="noopener noreferrer"&gt;django-nextjs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Django
&lt;/h3&gt;

&lt;p&gt;Django is a popular and fully featured server-side web framework, written in Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next.js
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Integrated Django + Next.js
&lt;/h2&gt;

&lt;p&gt;There are several approaches to using these two frameworks together, but we are using one of them.&lt;/p&gt;

&lt;p&gt;We are going to run Django and Next.js servers at the same time, use &lt;strong&gt;Django to accept web requests&lt;/strong&gt; and use &lt;strong&gt;Next.js as an internal service&lt;/strong&gt; that generates the HTML.&lt;/p&gt;

&lt;p&gt;Accordingly, Django handles web requests, and for each request, Next.js is called inside the Django view to get the HTML response.&lt;/p&gt;

&lt;p&gt;This is perfect &lt;strong&gt;if you already have a Django project&lt;/strong&gt;, and you don’t want to change anything and &lt;strong&gt;just start using Next.js&lt;/strong&gt; with it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can use this approach even if you are starting a new project&lt;/strong&gt; because you’ll be able to use more Django features (e.g. sessions).&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;You can use &lt;code&gt;django-nextjs&lt;/code&gt; in both development and production environments easily:&lt;/p&gt;

&lt;h3&gt;
  
  
  Development Environment
&lt;/h3&gt;

&lt;p&gt;When you run the project with &lt;code&gt;./manage.py runserver&lt;/code&gt;, you are using Django as a proxy for all the requests between you and Next.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AqsH_G4uOlzancerUQ3Z3VA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AqsH_G4uOlzancerUQ3Z3VA.png" alt="Development — django-nextjs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Production Environment
&lt;/h3&gt;

&lt;p&gt;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 &lt;a href="https://github.com/QueraTeam/django-nextjs" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A2f0gUgNgjTtqyNEAtLtW3A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A2f0gUgNgjTtqyNEAtLtW3A.png" alt="Production — django-nextjs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Code!
&lt;/h2&gt;

&lt;p&gt;Before we start, if you are already using django-channels in your project, or you need HMR (hot module replacement) you should set up &lt;code&gt;django-nextjs&lt;/code&gt; with &lt;code&gt;django-channels&lt;/code&gt;. Read it from our &lt;a href="https://github.com/QueraTeam/django-nextjs" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nextjs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create Next.js project inside your Django project (or anywhere you want):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the Next.js development server:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Next.js is up on port 3000, and in the / path shows the default welcome page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2070%2F1%2AResc3lH1bIGabvkBWTeC7A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2070%2F1%2AResc3lH1bIGabvkBWTeC7A.png" alt="The Next.js welcome page on port 3000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now our goal is to receive this page from a Django-powered server!&lt;/p&gt;

&lt;h3&gt;
  
  
  Django
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Install the &lt;code&gt;django-nextjs&lt;/code&gt; package, inside the same python environment, your Django project uses:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install django-nextjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add &lt;code&gt;django_nextjs&lt;/code&gt; to &lt;code&gt;INSTALLED_APPS&lt;/code&gt; in Django settings:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django_nextjs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Include the django-nextjs URLs inside your root &lt;code&gt;urls.py&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# myproject/urls.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;myapp.urls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;django_nextjs.urls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write the next.js page view inside your app:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# myapp/views.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django_nextjs.render&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render_nextjs_page_sync&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_nextjs_page_sync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the new view to &lt;code&gt;urls.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# myapp/urls.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the Django development server:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage.py runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we can see the Next.js page through the Django:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2070%2F1%2ADzvAyPrfbvgCdAU0qHU5zw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2070%2F1%2ADzvAyPrfbvgCdAU0qHU5zw.png" alt="The Next.js welcome page from the Django development server on port 8000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Notes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you need to show a Next.js page in another path in Django, feel free to use &lt;a href="https://nextjs.org/docs/api-reference/next.config.js/rewrites" rel="noopener noreferrer"&gt;Next.js Rewrites&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can extend Next.js pages in the Django layer if you need. Read more in django-nextjs &lt;a href="https://github.com/QueraTeam/django-nextjs" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;You can find django-nextjs on &lt;a href="https://pypi.org/project/django-nextjs/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; and &lt;a href="https://github.com/QueraTeam/django-nextjs" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://pypi.org/project/django-nextjs/" rel="noopener noreferrer"&gt;https://pypi.org/project/django-nextjs/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/QueraTeam/django-nextjs" rel="noopener noreferrer"&gt;https://github.com/QueraTeam/django-nextjs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project has been made with ❤️ and used &lt;a href="http://quera.org/magnet/jobs" rel="noopener noreferrer"&gt;on production&lt;/a&gt; for a year now. It’s pretty stable.&lt;/p&gt;

&lt;p&gt;Check out our other projects &lt;a href="https://github.com/QueraTeam" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt;.&lt;br&gt;
We appreciate your support.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/yourlabs/djnext" rel="noopener noreferrer"&gt;https://github.com/yourlabs/djnext&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/54252943/is-there-a-way-to-integrate-django-with-next-js#comment110078700_54252943" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/54252943/is-there-a-way-to-integrate-django-with-next-js#comment110078700_54252943&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>django</category>
      <category>nextjs</category>
      <category>python</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
