<?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: Niaz Morshed</title>
    <description>The latest articles on DEV Community by Niaz Morshed (@niazmorshed_).</description>
    <link>https://dev.to/niazmorshed_</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%2F961633%2F207e6983-4ac1-4838-a12a-12d9d49e2c03.png</url>
      <title>DEV Community: Niaz Morshed</title>
      <link>https://dev.to/niazmorshed_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/niazmorshed_"/>
    <language>en</language>
    <item>
      <title>How to protect your private routes in Next.js 13 &amp; Appwrite?</title>
      <dc:creator>Niaz Morshed</dc:creator>
      <pubDate>Mon, 03 Jul 2023 03:19:53 +0000</pubDate>
      <link>https://dev.to/niazmorshed_/how-to-protect-your-private-routes-in-nextjs-13-appwrite-4645</link>
      <guid>https://dev.to/niazmorshed_/how-to-protect-your-private-routes-in-nextjs-13-appwrite-4645</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In modern web development, security is paramount, especially when it comes to protecting sensitive data or functionality behind authentication barriers. Next.js 13, a popular React framework, combined with Appwrite, a self-hosted backend as a service platform, offers a powerful solution for building secure web applications. In this blog post, we will explore how to protect your private routes in Next.js 13 using Appwrite authentication. By implementing this approach, you can ensure that your private routes remain inaccessible to unauthenticated users, enhancing the overall security of your application. Let's dive in!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Understand Next.js and Appwrite
&lt;/h2&gt;

&lt;p&gt;Before diving into the details, let's take a higher-order look at what Next.js and Appwrite are. Next.js 13 is a powerful React framework that provides server-side rendering, static site generation, and other advanced features for building fast and scalable web applications. On the other hand, Appwrite is a backend as a service platform that simplifies common backend tasks, including user authentication, database management, and file storage. The combination of Next.js 13 and Appwrite empowers developers to create secure applications with ease.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Setting up Next.js and Appwrite
&lt;/h2&gt;

&lt;p&gt;To begin, we need to set up a Next.js 13 project and integrate Appwrite into it. This involves creating a new Next.js project and configuring the Appwrite SDK. By establishing this connection, we can leverage the all capabilities of Appwrite in our Next.js application.&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app &amp;lt;appname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running this command. Make sure your app is created and then change your directory to your app with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;appname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's install the Appwrite SDK by running the following command. (You can use yarn or pnpm or any of your choice)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;appwrite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that setup, now we can move on to the next part of configuring appwrite into our Next.js application. Open your code editor 🧑‍💻🧑‍💻!!!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;## Configuring Appwrite with Next.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we have appwrite in our app, it's time for us to use it with the best potential. Here is a folder structure I like, to manage appwrite services I'm using.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff566bpememmyltdril8h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff566bpememmyltdril8h.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So first of all let's work on the appwrite folder. In your &lt;code&gt;src&lt;/code&gt; folder make a new folder called &lt;code&gt;appwrite&lt;/code&gt; and make a &lt;code&gt;appwrite.ts&lt;/code&gt; file. Here is where we can manage apis to use different services of appwrite including authentication, database, storage and others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr39v6tqk3yk78cu6whz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr39v6tqk3yk78cu6whz.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the sake of this tutorial I'll show just the authentication part for appwrite just to keep things clean. Now in your &lt;code&gt;appwrite.ts&lt;/code&gt; file copy and paste this code and let's understand what it's doing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LoginInterface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RegisterInterface&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/interfaces/auth.interface&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Appwrite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;appwrite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;appwrite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Appwrite&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;appwrite&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cloud.appwrite.io/v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;************&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appwrite&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sdk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;createAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;registerBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RegisterInterface&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="nx"&gt;registerBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;registerBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;registerBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;loginBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoginInterface&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createEmailSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loginBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loginBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;deleteCurrentSession&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;current&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, we create an &lt;code&gt;api&lt;/code&gt; object where we instantiate Appwrite using &lt;code&gt;new Appwrite()&lt;/code&gt; and connect it to our project using &lt;code&gt;appwrite.setEndpoint("&lt;/code&gt;&lt;a href="https://cloud.appwrite.io/v1%22" rel="noopener noreferrer"&gt;&lt;code&gt;https://cloud.appwrite.io/v1").setProject("************")&lt;/code&gt;&lt;/a&gt;.setProject("************")). You will obtain the project ID from your Appwrite account.&lt;/p&gt;

&lt;p&gt;Next, we utilize &lt;code&gt;new Account(appwrite)&lt;/code&gt; to access the authentication APIs provided by Appwrite.&lt;/p&gt;

&lt;p&gt;After that, we define different functions for user registration, login, and authentication checking. These functions will be used to create services that can be efficiently utilized in our application.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Working with the services folder
&lt;/h2&gt;

&lt;p&gt;Now that we defined different functions for auth in the &lt;code&gt;appwrite.ts&lt;/code&gt; file it's time to gather all our services in one place! Create a new folder with the name &lt;code&gt;lib&lt;/code&gt; and inside that create &lt;code&gt;services&lt;/code&gt; folder. Here create a &lt;code&gt;auth.service.ts&lt;/code&gt; file. Here we'll write our auth services in one place so it's easy for us to manage.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngni2udluk2dlyfjegt0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngni2udluk2dlyfjegt0.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Now that you created let's copy and paste these code in `auth.service.ts` file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/appwrite/appwrite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LoginInterface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RegisterInterface&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/interfaces/auth.interface&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;registerBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RegisterInterface&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;registerBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error occurred during registration:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loginBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LoginInterface&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loginBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error occurred during login:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error occurred during getSession:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&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;/div&gt;



&lt;p&gt;In this file we created three services. One for &lt;code&gt;register&lt;/code&gt; , one for &lt;code&gt;login&lt;/code&gt; and one for cheking session (&lt;code&gt;getSession&lt;/code&gt;). Notice that we used the functions that we already wrote in the &lt;code&gt;appwrite.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Login and Signup
&lt;/h2&gt;

&lt;p&gt;Now that we have services set up, create your &lt;code&gt;login&lt;/code&gt; and &lt;code&gt;signup&lt;/code&gt; folder inside the the &lt;code&gt;(auth)&lt;/code&gt; group route. It will allow us to wrap our auth pages with a layout where we will check if the user is authenticated or not. If he is authenticated in this case we will redirect him to the main page of the app. Which will look in shortly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frxz5snvk1o98emzq9t6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frxz5snvk1o98emzq9t6h.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On both pages write as usual forms and use the `login` and `register` services exported from `auth.service.ts` . Now that have we created the login and register pages, it is now time to validate the user and implement the security of protected routes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Protect private routes 🔒🔒
&lt;/h2&gt;

&lt;p&gt;Now comes the final part of protecting our private routes. In order to protect your routes. Wrap your routes inside a group like &lt;code&gt;(protected)&lt;/code&gt; and add pages inside that group. But why we added this group? We added this to check users' session in the &lt;code&gt;layout.tsx&lt;/code&gt; file of this group and perform our actions for the unauthenticated user, in our case redirecting him to another page. Here is what it should look like:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3msfakf875o2da67r00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3msfakf875o2da67r00.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Now let's look at the code of `layout.tsx` file to understand how it works in real. Look at the closely:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Logo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/Logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Toaster&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/ui/toaster&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useToast&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/ui/use-toast&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getSession&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/services/auth.service&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProtectedLayout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useToast&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;destructive&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Session Expired&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;checkSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-screen h-screen fixed flex items-center justify-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Logo&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;animate-pulse&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Toaster&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ProtectedLayout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break it down together! In order to check users session we will need to use the react client component. But not freak if we create holes for other components to fit in this component with &lt;code&gt;{children}&lt;/code&gt; that will allow the any childrens to be server or client components.  &lt;/p&gt;

&lt;p&gt;Now get back to the main part. We created a &lt;code&gt;loading&lt;/code&gt; state to show some user-friendly loader when we are checking the session of user. Next in the &lt;code&gt;useEffect&lt;/code&gt; hook we all using the &lt;code&gt;getSession&lt;/code&gt; service that we defined in the &lt;code&gt;auth.service.ts&lt;/code&gt; file. After checking the session we can do whatever we wish for authenticated and unauthenticated user. In my case, for authenticated user I just set the loading state to false. And for unauthenticated user I performed some actions and redirected him back to the auth page.&lt;/p&gt;

&lt;p&gt;Similarly, you can check the user session in the &lt;code&gt;(auth)&lt;/code&gt; group and redirect users to dashboard/main page if the user is logged in.  &lt;/p&gt;

&lt;p&gt;Ad tada~~~!! You are now able to secure you application! 🔥🔥🔒&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning resources
&lt;/h2&gt;

&lt;p&gt;If you are looking for an example of how to work with Next.js 13 with Appwrite efficiently check out my repository on github. It has some best practices defined. Btw, stars ⭐ are appreciated 😜  &lt;/p&gt;

&lt;p&gt;The repository: &lt;a href="https://github.com/NiazMorshed2007/popwola" rel="noopener noreferrer"&gt;https://github.com/NiazMorshed2007/popwola&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions?
&lt;/h2&gt;

&lt;p&gt;If we haven't understand any part of it of have confusion feel free to ask in the comments. I'll be happy to help!&lt;/p&gt;

</description>
      <category>appwrite</category>
      <category>nextjs</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Popwola | Your no-code popup builder | Appwrite x Hashnode Hackathon</title>
      <dc:creator>Niaz Morshed</dc:creator>
      <pubDate>Sat, 10 Jun 2023 15:18:44 +0000</pubDate>
      <link>https://dev.to/niazmorshed_/popwola-your-no-code-popup-builder-appwrite-x-hashnode-hackathon-3gfp</link>
      <guid>https://dev.to/niazmorshed_/popwola-your-no-code-popup-builder-appwrite-x-hashnode-hackathon-3gfp</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/bMh8tO7KtlE?start=1"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  Team Members
&lt;/h2&gt;

&lt;p&gt;Niaz Morshed | &lt;a href="https://hashnode.com/@niazmorshed" rel="noopener noreferrer"&gt;Niaz Morshed&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Description
&lt;/h2&gt;

&lt;p&gt;Popwola is a no-code popup builder that simplifies the process of creating captivating popups. With its user-friendly interface and customizable templates, you can effortlessly design visually stunning popups without any coding complexities. Popwola also offers a preview option and timeline management for precise control over popup display. Boost user engagement and drive conversions with Popwola's seamless and efficient popup creation solution.&lt;/p&gt;
&lt;h3&gt;
  
  
  The problem we aimed to solve
&lt;/h3&gt;

&lt;p&gt;In today's digital landscape, user engagement is paramount for the success of online businesses and websites. Popups have proven to be highly effective in capturing attention and driving conversions. However, the process of creating popups often presents challenges, such as coding complexities, time-consuming tasks, and repetitive work. These tasks can be a significant drain on valuable time that could be better spent on coding innovative solutions. Recognizing this issue, Popwola was developed to provide a solution.&lt;/p&gt;
&lt;h3&gt;
  
  
  Introducing Popwola - The solution
&lt;/h3&gt;

&lt;p&gt;Popwola is a game-changing solution that addresses the challenges stated above.&lt;br&gt;&lt;br&gt;
Here is how it solves the problem (i.e Features) 👇👇&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Beautiful dashboard for managing: 🏠&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Popwola provides a beautiful and intuitive dashboard that simplifies the management of your popups. Easily navigate through your popup campaigns, and make necessary adjustments, all within a visually appealing and user-friendly interface.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftq5i28gtx10qkjnx19ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftq5i28gtx10qkjnx19ub.png" alt="Image description" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No-code editor: 🔨&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Popwola's no-code editor, you can create stunning popups without any coding required. Say goodbye to the complexities of coding and enjoy a seamless popup building experience. Customize the design, layout, and content of your popups effortlessly, making them visually captivating and engaging for your audience.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwds408qldux9dplwbv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwds408qldux9dplwbv4.png" alt="Image description" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Timeline management: ⌚&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take full control over the display duration of your popups with Popwola's timeline management feature. Specify the start and end dates for each popup, ensuring they appear at the right time and align with your promotional campaigns. This feature allows you to create a sense of urgency or time-sensitive offers, maximizing their impact on user engagement and conversions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Preview Option: 👁️&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Popwola offers a preview option that allows you to see exactly how your popups will appear on your website before going live. This feature enables you to optimize the design, layout, and messaging of your popups, ensuring they are visually appealing and effective in capturing your audience's attention.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Connect all with a single script!&lt;/strong&gt; 🪄⚡&lt;/p&gt;

&lt;p&gt;Say no to complex integrations. With Popwola, you can connect your popups to your website with just a single script. This streamlined integration saves you time and effort, allowing you to focus on creating compelling popup campaigns without the hassle of complicated setup processes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Development Phases
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Planning
&lt;/h3&gt;

&lt;p&gt;Yes, every successful project begins with careful planning. Recognizing the importance of laying a strong foundation, I dedicated long hours to meticulous planning. This involved selecting the key features, anticipating potential challenges, outlining the UI skeleton, mapping out the user journey, and conceptualizing the overall app design. To capture this pivotal moment, here's a picture that showcases my dedicated effort to planning...&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvz92ptkn5jqwdb7dy297.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvz92ptkn5jqwdb7dy297.png" alt="Image description" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After planning, it turns out that a lot of features could be implemented including conversion rate tracking, analytics, lead collection and many more. But I focused on some selected features for this release. The selected features are already mentioned on top.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Designing
&lt;/h3&gt;

&lt;p&gt;The design phase is a crucial stage in the development process, where the visual aesthetics and user experience of the project come to life. Here's an overview of the key steps involved in the design phase:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj35ijwsc7z33rr0sxsri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj35ijwsc7z33rr0sxsri.png" alt="Image description" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;i) Gathering Requirements: After carefully analyzing the project requirements, I identified the key pages that needed design attention. These pages include:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* A dashboard page for displaying instructions and important information.

* A profile page for users to customize their profiles.

* A campaigns page where all available campaigns will be listed.

* A campaign creation page for users to create new campaigns.

* An editor page for designing popups.

* A preview page for users to preview their campaigns.

* A library page for listing all available campaigns.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;ii) Research and Inspiration: To ensure a fresh and innovative design approach, I conducted thorough research and drew inspiration from various sources. Platforms like Dribbble and other design communities provided valuable insights and ideas. By immersing myself in design inspirations, I gained a clearer vision of the desired aesthetics and user experience.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Coding the App
&lt;/h3&gt;

&lt;p&gt;During the coding phase, it was mixed feelings of cry and joy. I brought the visual designs to life by implementing the functionalities of Popwola. Leveraging technologies like Next.js 13, &lt;a href="https://appwrite.io" rel="noopener noreferrer"&gt;Appwrite&lt;/a&gt; and TypeScript, I created reusable UI components and integrated features such as the no-code editor, timeline management, and preview option. Version control tools facilitated collaboration and maintained code integrity throughout the development process. The coding phase transformed the design into a fully functional app, ready to empower users with a seamless no-code popup building experience.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Tech stack used
&lt;/h2&gt;

&lt;p&gt;Popwola is built on top of hot technlogies including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;: A popular React framework for building fast and scalable applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://appwrite.io/" rel="noopener noreferrer"&gt;Appwrite&lt;/a&gt;: An open-source backend server that simplifies the development process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt;: A bunch of components kit for creating stunning UI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redux: For state management&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;: A statically typed superset of JavaScript that enhances code maintainability and developer productivity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;: A utility-first CSS framework that enables rapid UI development with pre-built components and customizable styling.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Features of appwrite used
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Authentication: 🔒&lt;/p&gt;

&lt;p&gt;I utilized Appwrite's incredibly user-friendly authentication system to add authentication to my app. I thoroughly enjoyed working with it!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Appwrite Database: 📃&lt;/p&gt;

&lt;p&gt;I leveraged the database to store data for my app. The document-based permission feature was particularly impressive and greatly enhanced data security.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Appwrite Storage: 🏬&lt;/p&gt;

&lt;p&gt;I integrated Appwrite's storage functionality to store popup images uploaded by users. This feature provided a seamless experience for managing and retrieving user-generated content.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Challenges I faced building it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Getting Familiar with Appwrite:&lt;/p&gt;

&lt;p&gt;When I first started using Appwrite, it took me some time to grasp its features and become comfortable with its functionalities. However, once I gained a better understanding, working with it became an enjoyable experience.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Setting Up Redux with the Editor:&lt;/p&gt;

&lt;p&gt;Integrating Redux with the editor posed a challenge. It required some effort to configure and establish the necessary connections between the two. However, once everything was properly set up, it greatly enhanced the functionality and user experience of the project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Creating the &lt;code&gt;script-min.js&lt;/code&gt; File for Seamless Popup Handling&lt;/p&gt;

&lt;p&gt;To ensure smooth and seamless handling of popups, I had to create the script-min.js file. This involved carefully designing the script to handle popups in a way that provided a seamless and user-friendly interaction. Although it required some extra work, the end result greatly improved the overall usability of the project.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Public Code Repository 🧑‍💻
&lt;/h2&gt;

&lt;p&gt;Here is a link to the public Github repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/NiazMorshed2007/popwola" rel="noopener noreferrer"&gt;https://github.com/NiazMorshed2007/popwola&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Live App
&lt;/h2&gt;

&lt;p&gt;Start building popups here: &lt;a href="https://popwola.vercel.app/" rel="noopener noreferrer"&gt;https://popwola.vercel.app/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  A video recording showing the workflow
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/AsgLX5u4YSo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This project has significant potential for growth and can effectively solve real-world problems. As an open-source initiative, it offers a valuable opportunity for collaboration and innovation in the realm of popup building. By expanding customization options, improving integration compatibility, implementing analytics capabilities, ensuring responsive design, and providing robust documentation and community support, this project can become a go-to resource for developers seeking to create powerful and user-friendly popups.  &lt;/p&gt;

&lt;p&gt;And, I had an incredible journey working on this project for the hackathon. Despite starting nearly two weeks behind schedule, I put in the effort and completed it successfully. I want to extend my heartfelt thanks to &lt;a href="https://appwrite.io" rel="noopener noreferrer"&gt;Appwrite&lt;/a&gt; and &lt;a href="https://hashnode.com" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt; for arranging this fantastic hackathon! I am truly grateful for the opportunity they provided and for their support throughout the process.&lt;/p&gt;

&lt;h1&gt;
  
  
  Appwrite #AppwriteHackathon
&lt;/h1&gt;

</description>
      <category>appwritehack</category>
      <category>nextjs</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A comprehensive guide to Next.js 13 App Router - Part 1</title>
      <dc:creator>Niaz Morshed</dc:creator>
      <pubDate>Fri, 26 May 2023 17:15:58 +0000</pubDate>
      <link>https://dev.to/niazmorshed_/a-comprehensive-guide-to-nextjs-13-app-router-part-1-41ki</link>
      <guid>https://dev.to/niazmorshed_/a-comprehensive-guide-to-nextjs-13-app-router-part-1-41ki</guid>
      <description>&lt;p&gt;Next.js is a powerful framework for building server-side rendered React applications. One of its key features for routing is the App Router which was introduced in version 13, which allows you to define and organize routes in your Next.js application. In this comprehensive guide, we will explore the main concepts and techniques of Next.js App Router, providing you with the knowledge to effectively navigate and structure your Next.js applications. Let's dive straight into it 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Routes
&lt;/h2&gt;

&lt;p&gt;In Next.js version 12 we were used to create routes with a &lt;code&gt;js&lt;/code&gt; / &lt;code&gt;jsx&lt;/code&gt; or &lt;code&gt;ts&lt;/code&gt; / &lt;code&gt;tsx&lt;/code&gt; file inside the pages directory. But now in version 13 we define routes inside the &lt;code&gt;app&lt;/code&gt; directory, with a &lt;code&gt;directory&lt;/code&gt; (note: not a file). Each folder/direcotry represents a &lt;strong&gt;route&lt;/strong&gt; segment that maps to a &lt;strong&gt;URL&lt;/strong&gt; segment. Here is a visual for you to understand:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyivos9qyg64y66u6cvr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyivos9qyg64y66u6cvr.png" alt="routes example" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can use a special file &lt;code&gt;page.js&lt;/code&gt; to make our pages accessible. If you don't add any &lt;code&gt;page.js&lt;/code&gt; file inside route folder we won't see anything on the route.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4cfa0dhkdxtccspicbk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4cfa0dhkdxtccspicbk.png" alt="preview in public" width="732" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here the &lt;code&gt;analytics&lt;/code&gt; route will not work because it hasn't any &lt;code&gt;page.js&lt;/code&gt; inside it. This folder could be used to store components, stylesheets, images, or other colocated files.&lt;/p&gt;

&lt;p&gt;Here is a code example of creating &lt;code&gt;app/page.js&lt;/code&gt; page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// `app/page.js` is the UI for the `/` URL&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layout
&lt;/h3&gt;

&lt;p&gt;A layout is UI that is &lt;strong&gt;shared&lt;/strong&gt; between multiple pages. On navigation, layouts preserve state, remain interactive, and do not re-render.&lt;/p&gt;

&lt;p&gt;To define a layout, you can start by creating a file called &lt;code&gt;layout.js&lt;/code&gt; within the desired directory. This file will export a default React component that represents the layout. The component should accept a &lt;code&gt;children&lt;/code&gt; prop, which will be populated with either a "child layout" or a "child page" during rendering.&lt;/p&gt;

&lt;p&gt;For instance, let's consider a Typescript example of a &lt;code&gt;layout.tsx&lt;/code&gt; file located at &lt;code&gt;app/dashboard/layout.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DashboardLayout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// represents a page or nested layout&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Include shared UI here, such as a header or sidebar */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;nav&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/nav&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/section&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;DashboardLayout&lt;/code&gt; component serves as the default layout for the dashboard section of your application. It receives the &lt;code&gt;children&lt;/code&gt; prop, which dynamically renders the content within the layout. The &lt;code&gt;children&lt;/code&gt; prop can be a page or another nested layout. Here is a visual for you to understand better:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nncx62hne4hf4lysy8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nncx62hne4hf4lysy8z.png" alt="layout in next.js" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic Routes
&lt;/h2&gt;

&lt;p&gt;In Next.js App Router, dynamic routes allow you to generate routes based on dynamic data, making it easy to handle varying segment names and create dynamic paths. Whether you need to generate routes at request time or pre-render them during build time, dynamic segments provide the flexibility you need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Convention for Dynamic Segments
&lt;/h3&gt;

&lt;p&gt;To create a dynamic segment, you can enclose a folder's name in square brackets, such as &lt;code&gt;[folderName]&lt;/code&gt;. For example, &lt;code&gt;[id]&lt;/code&gt; or &lt;code&gt;[slug]&lt;/code&gt; can be used as dynamic segments.&lt;/p&gt;

&lt;p&gt;Dynamic segments are then passed as the &lt;code&gt;params&lt;/code&gt; prop to &lt;code&gt;layout&lt;/code&gt;, &lt;code&gt;page&lt;/code&gt;, &lt;code&gt;route&lt;/code&gt;, and &lt;code&gt;generateMetadata&lt;/code&gt; functions, allowing you to access the dynamic values within your components.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example: Blog routes&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For instance, if you have a blog where each post has a unique slug, you can define a route like this: &lt;code&gt;app/blog/[slug]/page.js&lt;/code&gt;, where &lt;code&gt;[slug]&lt;/code&gt; represents the dynamic segment for the blog posts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;Page&lt;/code&gt; component receives the &lt;code&gt;params&lt;/code&gt; prop, which contains the dynamic values from the URL. For the URL &lt;code&gt;/blog/a&lt;/code&gt;, &lt;code&gt;params&lt;/code&gt; would be &lt;code&gt;{ slug: 'a' }&lt;/code&gt;, allowing you to render the appropriate content based on the dynamic segment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generating Static Params
&lt;/h3&gt;

&lt;p&gt;To generate routes at build time, you can use the &lt;code&gt;generateStaticParams&lt;/code&gt; function in combination with dynamic route segments. This function allows you to retrieve data smartly and efficiently, reducing build times by automatically deduplicating fetch requests with the same arguments.&lt;/p&gt;

&lt;p&gt;For example, let's consider an example of generating static params for the blog post routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateStaticParams&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://.../posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&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;/div&gt;



&lt;p&gt;In this scenario, the &lt;code&gt;generateStaticParams&lt;/code&gt; function fetches the blog posts and generates the static params based on the retrieved data. This approach improves performance by pre-rendering the routes during the build process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Catch-all Segments
&lt;/h3&gt;

&lt;p&gt;Dynamic segments can be extended to match subsequent segments by adding an ellipsis inside the brackets, such as &lt;code&gt;[...folderName]&lt;/code&gt;. For example, &lt;code&gt;app/shop/[...slug]/page.js&lt;/code&gt; would match &lt;code&gt;/shop/clothes&lt;/code&gt;, &lt;code&gt;/shop/clothes/tops&lt;/code&gt;, &lt;code&gt;/shop/clothes/tops/t-shirts&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional Catch-all Segments
&lt;/h3&gt;

&lt;p&gt;Additionally, catch-all segments can be made optional by including the parameter in double square brackets, like &lt;code&gt;[[...folderName]]&lt;/code&gt;. This allows the route to match with or without the catch-all segment. For example, &lt;code&gt;app/shop/[[...slug]]/page.js&lt;/code&gt; would match &lt;code&gt;/shop&lt;/code&gt;, as well as &lt;code&gt;/shop/clothes&lt;/code&gt;, &lt;code&gt;/shop/clothes/tops&lt;/code&gt;, and &lt;code&gt;/shop/clothes/tops/t-shirts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By utilizing dynamic routes and their variations, you can create powerful and flexible routing structures in your Next.js applications. Whether you need to handle dynamic data or generate routes dynamically, these features provide the necessary tools to build dynamic and engaging user experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Next.js Docs: &lt;a href="https://nextjs.org/docs/app/building-your-application/routing" rel="noopener noreferrer"&gt;https://nextjs.org/docs/app/building-your-application/routing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5wyu6oneggddl6o87mpr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5wyu6oneggddl6o87mpr.png" alt="thanks for reading" width="700" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hey! You reached the bottom. Thanks for the read 😍
&lt;/h2&gt;

&lt;p&gt;Stay tuned for Part 2 of a comprehensive guide to Next.js App Router, where we'll explore more advanced techniques and features to further enhance your application's routing capabilities.&lt;/p&gt;

&lt;p&gt;If you want to connect with me or want to have a chat, feel free to connect with me. I would like to talk to you!&lt;/p&gt;

&lt;p&gt;- &lt;a href="https://twitter.com/niazmorshed_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;&lt;br&gt;
- &lt;a href="https://github.com/NiazMorshed2007" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;br&gt;&lt;br&gt;
- &lt;a href="https://www.linkedin.com/in/niazmorsheddev/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>react</category>
    </item>
    <item>
      <title>Ensure Code Separation in Next.js: Server Only vs Client Components</title>
      <dc:creator>Niaz Morshed</dc:creator>
      <pubDate>Wed, 24 May 2023 17:15:45 +0000</pubDate>
      <link>https://dev.to/niazmorshed_/ensure-code-separation-in-nextjs-server-only-vs-client-components-20pl</link>
      <guid>https://dev.to/niazmorshed_/ensure-code-separation-in-nextjs-server-only-vs-client-components-20pl</guid>
      <description>&lt;p&gt;Next.js is a popular framework for building server-rendered React applications. However, when JavaScript modules are shared between server and client components, it can introduce a potential vulnerability. This blog post will explore the risks associated with server-only code leaking into client components and present a solution using the "server-only" package in Next.js. We will learn how to identify and restrict server-specific code from being imported into client components, ensuring code integrity and security.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Understanding the Risk&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When developing web applications, it is essential to differentiate between code that should only run on the server and code suitable for client-side execution. Failure to do so can result in the leakage of sensitive information or the execution of code in an unintended context. Let's examine an example to understand this risk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/data.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://external-service.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;/div&gt;



&lt;p&gt;In the above code snippet, &lt;code&gt;getData()&lt;/code&gt; appears to work on both the server and the client. However, the &lt;code&gt;authorization&lt;/code&gt; header relies on the &lt;code&gt;process.env.API_KEY&lt;/code&gt;, which is a private environment variable accessible only on the server. Next.js automatically replaces private environment variables with an empty string in client code to prevent the leakage of secure information. Consequently, although &lt;code&gt;getData()&lt;/code&gt; can be imported and executed on the client, it won't function as intended. Making the variable public would resolve the issue but would compromise sensitive information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Meet &lt;strong&gt;the "server-only" Package&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To prevent the accidental usage of server-only code in client components, Next.js provides the "server-only" package. This package helps developers identify and restrict the usage of server-specific code, ensuring its execution exclusively on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Installation&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the "server-only" package using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;server-only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Implementation&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now importing the "server-only" package, any client component that attempts to import the server-only module will encounter a build-time error, clearly indicating that the module can only be used on the server.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/data.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;server-only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Code that should only run on the server&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bonus 🔥
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Handling Client-Only Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next.js also offers the "client-only" package to handle modules containing client-only code, such as those relying on browser-specific APIs like the window object. Marking modules with "client-only" ensures they are only used on the client-side, preventing unintended access or execution on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Installation&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the "client-only" package using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;client-only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Implementation&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By importing the "client-only" package, any server component that mistakenly imports the client-only module will generate a build-time error, notifying developers that the module can only be used on the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/client-only-module.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;client-only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Client-only code utilizing browser-specific APIs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Like what you see? 💘
&lt;/h2&gt;

&lt;p&gt;Feel free to follow me on Twitter, GitHub, and LinkedIn for more articles and insights on Next.js and other frontend development topics. Let's connect and stay updated on the latest trends and techniques in the world of web development!&lt;/p&gt;

&lt;p&gt;- &lt;a href="https://twitter.com/niazmorshed_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;&lt;br&gt;
- &lt;a href="https://github.com/NiazMorshed2007" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;br&gt;&lt;br&gt;
- &lt;a href="https://www.linkedin.com/in/niazmorsheddev/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>react</category>
    </item>
    <item>
      <title>Component Patterns in Next.js 13</title>
      <dc:creator>Niaz Morshed</dc:creator>
      <pubDate>Mon, 22 May 2023 16:24:11 +0000</pubDate>
      <link>https://dev.to/niazmorshed_/component-patterns-in-nextjs-13-1apg</link>
      <guid>https://dev.to/niazmorshed_/component-patterns-in-nextjs-13-1apg</guid>
      <description>&lt;p&gt;When it comes to building robust web applications, performance optimization is a crucial consideration. Slow-loading websites can result in frustrated users and lost opportunities. Fortunately, Next.js, the popular React framework, offers a range of powerful features to tackle performance challenges head-on. In this article, we will dive into the latest patterns for Next.js 13, empowering you to design a highly efficient component tree and explore strategies for leveraging the strengths of client and server components. By the end, you'll be equipped with the knowledge and techniques to deliver blazing-fast web experiences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client Components at the Outermost Leaves
&lt;/h3&gt;

&lt;p&gt;To boost the performance of your application, Next.js recommends moving your client component to the outermost leaves of your component tree whenever possible.&lt;/p&gt;

&lt;p&gt;For instance, suppose you have a Layout component that consists of static elements like a logo and links, alongside an interactive search bar that relies on state. Instead of making the entire layout a Client Component, it's preferable to extract the interactive logic into its Client Component, such as the &amp;lt;SearchBar /&amp;gt;. By doing so, the layout can remain as a Server Component, eliminating the need to send unnecessary component JavaScript to the client.&lt;/p&gt;

&lt;p&gt;Here is a visual of how it's working:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytjhfjvfeq0s74qnnd4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytjhfjvfeq0s74qnnd4g.png" alt="Image description" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a code example of how Next.js recommends you extract your client component into the outermost branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SearchBar is a Client Component&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SearchBar&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./searchbar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Logo remains a Server Component&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Logo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./logo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;nav&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Logo&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SearchBar&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/nav&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/div&gt;



&lt;p&gt;By applying this approach, you ensure that only the necessary components are rendered on the client side, leading to improved performance and reduced resource overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Composing Client and Server Components&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Server and Client Components can be combined in the same component tree.&lt;/p&gt;

&lt;p&gt;Behind the scenes, React handles rendering as follows:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Phase1:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When the server kicks into action, React diligently renders all the Server Components, ensuring they're ready before being sent to the client. This rendering phase even covers Server Components nestled inside Client Components. During this server-side rendering, React wisely skips any Client Components it encounters, allowing them to shine later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdvmje56uhtyqbpauczw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdvmje56uhtyqbpauczw.png" alt="Image description" width="778" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Phase2:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, enter the client-side realm. React takes the stage again, this time rendering the Client Components and seamlessly merging the work done on both the server and client sides. If a Client Component happens to house any Server Components, fear not. React ensures that the rendered content of those Server Components is placed precisely where it belongs within the Client Component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm34xdy7v3cy2mh7e11lz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm34xdy7v3cy2mh7e11lz.png" alt="Image description" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Nesting Server Components within Client Components
&lt;/h3&gt;

&lt;p&gt;When it comes to integrating Server Components within Client Components in Next.js, there are certain restrictions to consider. Directly importing a Server Component into a Client Component is not supported, as it would require an additional server round trip, impacting performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Unsupported Pattern: Importing a Server Component into a Client Component&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The following code pattern is not supported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// This pattern will **not** work!&lt;/span&gt;
&lt;span class="c1"&gt;// You cannot import a Server Component into a Client Component.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ExampleServerComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example-server-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ExampleClientComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ExampleServerComponent&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Recommended Pattern: Passing Server Components as Props to Client Components&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead, Next.js recommends utilizing React props to create placeholders, or "holes," for Server Components within Client Components. This ensures optimal performance and decoupling of rendering.&lt;/p&gt;

&lt;p&gt;The recommended pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// this pattern will work&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ExampleClientComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/div&gt;



&lt;p&gt;In this pattern, the ExampleClientComponent doesn't know the content of its children prop or that it will eventually be filled by the result of a Server Component. Its responsibility is solely to determine where the children should be placed.&lt;/p&gt;

&lt;p&gt;The parent server component usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This pattern works:&lt;/span&gt;
&lt;span class="c1"&gt;// You can pass a Server Component as a child or prop of a Client Component.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ExampleClientComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example-client-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ExampleServerComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example-server-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ExampleClientComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ExampleServerComponent&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ExampleClientComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;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;/div&gt;



&lt;p&gt;By following this recommended pattern, Next.js empowers developers to compose components efficiently, improving performance and maintaining the separation of concerns between server-side and client-side rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In conclusion, Next.js provides powerful features and patterns to optimize performance in web applications. By strategically placing client components at the outermost leaves of the component tree, unnecessary JavaScript can be avoided, resulting in improved performance and reduced resource overhead. Additionally, Next.js allows for the seamless composition of client and server components, leveraging server-side rendering to ensure efficient rendering and merging of components on the client-side. When integrating server components within client components, it is important to follow the recommended pattern of using React props to pass server components as placeholders, enabling optimal performance and decoupling of rendering. By implementing these techniques and leveraging the strengths of Next.js, developers can deliver blazing-fast web experiences and enhance the overall performance of their applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Like what you see? 💘
&lt;/h3&gt;

&lt;p&gt;Feel free to follow me on Twitter, GitHub, and LinkedIn for more articles and insights on Next.js and other frontend development topics. Let's connect and stay updated on the latest trends and techniques in the world of web development!  &lt;/p&gt;

&lt;p&gt;- &lt;a href="https://twitter.com/niazmorshed_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;&lt;br&gt;
- &lt;a href="https://github.com/NiazMorshed2007" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;br&gt;&lt;br&gt;
- &lt;a href="https://www.linkedin.com/in/niazmorsheddev/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Choosing Between Server and Client Components in Next.js</title>
      <dc:creator>Niaz Morshed</dc:creator>
      <pubDate>Mon, 22 May 2023 06:27:45 +0000</pubDate>
      <link>https://dev.to/niazmorshed_/choosing-between-server-and-client-components-in-nextjs-jaf</link>
      <guid>https://dev.to/niazmorshed_/choosing-between-server-and-client-components-in-nextjs-jaf</guid>
      <description>&lt;p&gt;In Next.js, deciding whether to use Server Components or Client Components can have a significant impact on your application's performance and functionality. In this blog post, we will explore the use cases for each component type and guide when to choose Server Components or Client Components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Server Components and Client Components
&lt;/h2&gt;

&lt;p&gt;Server Components are the default choice in Next.js. They execute on the server, allowing you to fetch data, access backend resources directly, and keep sensitive information like access tokens and API keys secure.&lt;/p&gt;

&lt;p&gt;On the other hand, Client Components are executed on the client-side, providing interactivity and leveraging browser-only APIs. They are useful for adding event listeners, managing state with hooks like useState() and useReducer().&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing Between Server and Client Components
&lt;/h3&gt;

&lt;p&gt;To simplify the decision-making process, let's consider the different use cases for Server Components and Client Components:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;th&gt;Server Components&lt;/th&gt;
&lt;th&gt;Client Components&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fetch data.&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access backend resources (directly)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep sensitive information on the server (access tokens, API keys, etc)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep large dependencies on the server / Reduce client-side JavaScript&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add interactivity and event listeners (&lt;code&gt;onClick()&lt;/code&gt;, &lt;code&gt;onChange()&lt;/code&gt;, etc)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use State and Lifecycle Effects (&lt;code&gt;useState()&lt;/code&gt;, &lt;code&gt;useReducer()&lt;/code&gt;, &lt;code&gt;useEffect()&lt;/code&gt;, etc)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use browser-only APIs&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use custom hooks that depend on state, effects, or browser-only APIs&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use React Class Components&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note: The decision between Server Components and Client Components ultimately depends on the specific requirements of your application and the nature of the task at hand. Consider the strengths and limitations of each component type when making your architectural choices.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
