<?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>Forem: Thomas Desmond</title>
    <description>The latest articles on Forem by Thomas Desmond (@thetombomb).</description>
    <link>https://forem.com/thetombomb</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%2F710788%2Fc2a48184-31ab-4df3-a35c-861450648758.jpg</url>
      <title>Forem: Thomas Desmond</title>
      <link>https://forem.com/thetombomb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thetombomb"/>
    <language>en</language>
    <item>
      <title>Cloudflare Pages and Next.js: I'm Not Recommending It</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Wed, 01 May 2024 14:28:48 +0000</pubDate>
      <link>https://forem.com/thetombomb/cloudflare-pages-and-nextjs-im-not-recommending-it-5co6</link>
      <guid>https://forem.com/thetombomb/cloudflare-pages-and-nextjs-im-not-recommending-it-5co6</guid>
      <description>&lt;p&gt;As a developer, I am always looking for ways to test the limits of different hosting providers and see how well they support different frameworks and technologies. I recently tested Cloudflare Pages with my Next.js app, and the results differed from what I expected. In this article, I'll walk you through my experience and the changes I had to make to get my app to work on Cloudflare Pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next.js Host Check App
&lt;/h2&gt;

&lt;p&gt;Before I dive into my experience with Cloudflare Pages, let me give you some background on my app. I have built an app that tests 13 of the most essential features of Next.js Pages Architecture. These features include server-side rendering, image optimization, and API routes, among others. I've put Cloudflare Pages to the test. I'm deploying this application on different hosting providers to see how well they support Next.js and what features they do and don't support. &lt;/p&gt;

&lt;p&gt;My app is a Next.js Pages Architecture application built with version 13.4.16. I attempted to deploy it out of the box to different hosting providers. However, I ran into some difficulties with Cloudflare Pages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/thomas-desmond/host-check-nextjs"&gt;GitHub: Host-Check-Next.js&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with Next.js on Cloudflare Pages
&lt;/h2&gt;

&lt;p&gt;The biggest thing I came across was the edge runtime requirement. All server-side routes in your Next.js project must be configured as edge runtime routes. When running on Cloudflare Pages, you must add &lt;code&gt;export const runtime=edge&lt;/code&gt; to each server route.&lt;/p&gt;

&lt;p&gt;This means you are limited to the edge runtime for Incremental Static Regeneration (ISR), getServerSideProps(), API Routes, and everything else server-side. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❓ What is the Edge Runtime? From Vercel, the edge runtime provides a subset of web APIs such as fetch, request, and response. This lightweight API layer is built to be performant and execute code with minimal latency. See &lt;a href="https://vercel.com/docs/functions/runtimes/edge-runtime"&gt;Vercel's documentation&lt;/a&gt; for a full list of available APIs. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, I added the line &lt;code&gt;export const runtime=edge&lt;/code&gt; to every file, but the build still failed. Instead, I had to use &lt;code&gt;export const runtime=experimental-edge&lt;/code&gt;, which got my Next.js app to at least build in Cloudflare Pages. &lt;/p&gt;

&lt;p&gt;But that was not the end of my problems. I had to add a &lt;code&gt;nodejs_compat&lt;/code&gt; flag within Cloudflare Pages. I'm not sure why, but I did.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfg33oq5hzy8jv8t4fx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfg33oq5hzy8jv8t4fx0.png" alt="Cloudflare Pages Node Compatability Error" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After one more final rebuild, my app was built and deployed correctly. I could access my application live and deploy it to the web. Finally, it was time to test what features of Next.js worked. &lt;/p&gt;

&lt;h2&gt;
  
  
  Next.js Feature Support in Cloudflare Pages
&lt;/h2&gt;

&lt;p&gt;With the &lt;a href="https://github.com/thomas-desmond/host-check-nextjs"&gt;host-check-nextjs&lt;/a&gt; app deployed to Cloudflare Pages, I could now run the automated Cypress tests against the deployed app. &lt;br&gt;
Here are the results of the automated testing. These are the worst results so far in my testing of Next.js hosting providers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Next.js Feature Support&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Next.js Version 13.4.16 Pages Architecture&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getStaticProps()&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getServerSideProps()&lt;/td&gt;
&lt;td&gt;⚠ (Edge Runtime Only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image Optimization&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incremental Static Regeneration (ISR)&lt;/td&gt;
&lt;td&gt;⚠ (Edge Runtime Only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Routes&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Middleware Redirects&lt;/td&gt;
&lt;td&gt;⚠ (Edge Runtime Only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge Runtime&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic Routes&lt;/td&gt;
&lt;td&gt;⚠ (Edge Runtime Only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;next.config.js Redirects&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;next.config.js Rewrites&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sub-path Internationalization&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sitecore JSS Image Optimization&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;While still working, the edge runtime limits anything that runs on the server, like ISR and getServerSideProps(). You can also see standard API routes are not working and no out of the box image optimization. &lt;/p&gt;

&lt;p&gt;The absence of image optimization is a major issue for me. Optimized images are essential to creating a modern and efficient website. The fact that Cloudflare Pages does not utilize the built-in &lt;code&gt;next/image&lt;/code&gt; components, which are designed to optimize images for the web, is a deal breaker. This could lead to slower page load times and a less optimal user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, my experience with Cloudflare Pages and Next.js was challenging, but I got my app to work with some specific changes. Cloudflare Pages only supports the edge runtime for its server-side routes, so you are limited to the available APIs. However, Cloudflare Pages might be perfect if you're looking for a more performant edge runtime with a smaller minimal latency API layer— I don't expect the number of people with that specific need to be very high. &lt;/p&gt;

&lt;p&gt;Understanding the limitations and requirements when working with Cloudflare Pages and Next.js is crucial. This post aims to provide you with valuable insights from my experience, equipping you with the knowledge you need for your own testing and deployment of Next.js apps.&lt;/p&gt;

&lt;p&gt;Interested in other Next.js hosting providers? Check out my other test runs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thetombomb.com/posts/aws-amplify-nextjs-pages"&gt;AWS Amplify Support for Next.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.thetombomb.com/posts/azure-swa-nextjs-pages"&gt;How Well Does Azure Static Web Apps (SWA) Support Next.js?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or watch the video version of this article: &lt;a href="https://youtu.be/F7PLcfzF-z0"&gt;Why Cloudflare Pages May Not Be the Best For Next.js 🤷‍♂️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>cloudflare</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How Well Does Azure Static Web Apps (SWA) Support Next.js? | Pages Architecture</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Wed, 10 Apr 2024 14:33:09 +0000</pubDate>
      <link>https://forem.com/thetombomb/how-well-does-azure-static-web-apps-swa-support-nextjs-pages-architecture-43f9</link>
      <guid>https://forem.com/thetombomb/how-well-does-azure-static-web-apps-swa-support-nextjs-pages-architecture-43f9</guid>
      <description>&lt;p&gt;I have developed an application that focuses on isolating and testing the most essential features of Next.js. After creating the app, I deployed it to Azure Static Web Apps (SWA). Recently, SWA updated its platform, and I was excited to see how their improvements have impacted Next.js. To my surprise, the improvements were impressive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 The current app uses the Pages-based architecture; I plan to develop an App Router Next.js application very soon. Give the &lt;a href="https://github.com/thomas-desmond/host-check-nextjs"&gt;repo&lt;/a&gt; a ⭐.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Next.js Application Overview
&lt;/h2&gt;

&lt;p&gt;The Next.js application I deployed is publicly available and &lt;a href="https://github.com/thomas-desmond/host-check-nextjs"&gt;open-source on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Essential factors of the app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js version 13.4.16&lt;/li&gt;
&lt;li&gt;Pages-based Architecture&lt;/li&gt;
&lt;li&gt;Sitecore JSS version 21.6.3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details on the app, check out my earlier article: &lt;a href="https://thetombomb.com/posts/nextjs-every-feature-part1"&gt;Exploring Every Feature in Next.js and Testing Hosting Providers&lt;/a&gt; or YouTube Video: &lt;a href="https://youtu.be/hsRmywPiYqU"&gt;Using Every Next.js Feature to Test Hosting Providers (Part 1)&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Deployed the Next.js Application
&lt;/h2&gt;

&lt;p&gt;I followed the &lt;a href="https://learn.microsoft.com/en-us/azure/static-web-apps/deploy-nextjs-hybrid"&gt;Deploy hybrid Next.js websites on Azure Static Web Apps (Preview)&lt;/a&gt; documentation to deploy my app. I didn't make any configuration changes, so it was an out-of-the-box deployment of Next.js to Azure Static Web Apps.&lt;/p&gt;

&lt;p&gt;Although Next.js support has been in preview on Azure SWA for years, this latest release makes me expect it to be out of preview soon. However, I am not hosting production Next.js applications in SWA since support is still in preview.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next.js Support in Azure Static Web Apps
&lt;/h2&gt;

&lt;p&gt;I was presently surprised that Azure Static Webs Apps had full support for every feature I tested. I ran my automated Cypress tests against the deployed Next.js app, and every test passed.&lt;/p&gt;

&lt;p&gt;Check out the table to see every feature tested and the results.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Next.js Feature Support&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Next.js Version 13.4.16 Pages Architecture&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getStaticProps()&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;getServerSideProps()&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image Optimization&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incremental Static Regeneration (ISR)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Routes&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Middleware Redirects&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge Runtime&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic Routes&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;next.config.js Redirects&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;next.config.js Rewrites&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sub-path Internationalization&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sitecore JSS Image Optimization&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Based on the test results, Azure Static Web Apps is a suitable platform to host a Pages-based Next.js application on version 13. However, it's important to note that SWA Next.js support is still in preview, so it's not recommended for production deployments yet. &lt;/p&gt;

&lt;p&gt;I tested a pages-based Next.js 14 app, which failed due to Node version issues. I haven't investigated further, but Node 14 deployments do not work out of the box for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Test Hosting Providers Yourself
&lt;/h2&gt;

&lt;p&gt;Want to test Azure Static Web Apps for yourself? Have a specific version of Next.js that you need to test.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Fork my open-source repository on GitHub: &lt;a href="https://github.com/thomas-desmond/host-check-nextjs"&gt;https://github.com/thomas-desmond/host-check-nextjs&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Remember to give the repo a star! ⭐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Deploy the Next.js to your hosting provider&lt;/li&gt;
&lt;li&gt; Change the &lt;code&gt;url&lt;/code&gt; environment variable in the &lt;code&gt;cypress.config.ts&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt; Run the automated Cypress end-to-end tests and see the results

&lt;ol&gt;
&lt;li&gt; Open cypress test window &lt;code&gt;npm run cypress:open&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Choose E2E Tests&lt;/li&gt;
&lt;li&gt; Choose your preferred browser&lt;/li&gt;
&lt;li&gt; Run all the specs (tests)&lt;/li&gt;
&lt;li&gt; Review the results of the tests&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Watch the YouTube video version of this content: &lt;a href="https://youtu.be/XS0Ihz267_I"&gt;Testing Azure Static Web Apps Support for Next.js | Pages Architecture&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>azure</category>
      <category>hosting</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Exploring Every Feature in Next.js and Testing Hosting Providers</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Wed, 13 Mar 2024 16:40:17 +0000</pubDate>
      <link>https://forem.com/thetombomb/exploring-every-feature-in-nextjs-and-testing-hosting-providers-n5c</link>
      <guid>https://forem.com/thetombomb/exploring-every-feature-in-nextjs-and-testing-hosting-providers-n5c</guid>
      <description>&lt;p&gt;Today, I want to share with you a project I'm currently working on - a new Next.js project that will use every feature of Next.js. Join me as I delve into the intricacies of this project, exploring every feature that Next.js has to offer.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Project Overview
&lt;/h3&gt;

&lt;p&gt;In this project, I utilize every feature of Next.js, from statically rendered pages to API routes and everything in between. My focus is not just on showcasing these features but creating an app where each feature is isolated and individually testable. Why is it individually testable? The goal is to test various hosting providers to see how well they support these Next.js features.&lt;/p&gt;

&lt;p&gt;We know the big two, Vercel and Netlify, have fantastic support for Next.js. But what about all the others popping up? AWS Amplify? Azure Static Web Apps? Cloudflare Pages? How well do they support Next.js' plethora of features? &lt;/p&gt;

&lt;p&gt;I'm using the Pages-based architecture of Next.js for this first run and hope to have enough support to take on App router features next. &lt;/p&gt;

&lt;h3&gt;
  
  
  Testing and Automation
&lt;/h3&gt;

&lt;p&gt;Unlike traditional projects, my approach is to build an app that isolates each feature to a page, making it easier to test and evaluate. This allows me to generate a report on what is actually supported and working on any given hosting provider. So far, I have tested eleven of the Next.js features. &lt;/p&gt;

&lt;p&gt;I am creating automated Cypress end-to-end tests to assess each feature of Next.js. The plan is to host the test application on a hosting provider of your choice and then direct the Cypress tests toward the hosted solution. By determining which tests pass or fail, you can gain insight into the hosting provider's capabilities and compatibility with Next.js features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Prospects
&lt;/h3&gt;

&lt;p&gt;My vision for this project is to create a robust platform that provides insights into the compatibility of Next.js features with various hosting providers. This can help developers make informed decisions when choosing a project hosting platform.&lt;/p&gt;

&lt;p&gt;Give developers confidence that the version and features of Next.js that they require work before they go too deep into their solutions. &lt;/p&gt;

&lt;h3&gt;
  
  
  Join Me on this Journey
&lt;/h3&gt;

&lt;p&gt;Please follow along as I continue to develop this project. Your feedback and insights are invaluable as I strive to make this app a comprehensive testing ground for Next.js features. I want to make sure this app is helpful to everyone, not just myself. &lt;/p&gt;

&lt;p&gt;Share your thoughts on the features you use in your Next.js applications and the hosting providers you are considering. &lt;/p&gt;

&lt;h3&gt;
  
  
  Stay Tuned for More
&lt;/h3&gt;

&lt;p&gt;If you're intrigued by this project and want to see how it unfolds, consider subscribing to my new YouTube channel, &lt;a href="https://www.youtube.com/channel/UCMf4Vi87OVQgEX8XAYSCf0w"&gt;Thomas Does Dev&lt;/a&gt;. That is where I'll have the most up-to-date information on this project. &lt;/p&gt;

&lt;p&gt;In the upcoming parts of this series, I'll explore new features and test different hosting providers. &lt;/p&gt;

&lt;p&gt;Check out the code: &lt;a href="https://github.com/thomas-desmond/host-check-nextjs"&gt;Next.js Every Feature&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Watch the &lt;a href="https://youtu.be/hsRmywPiYqU"&gt;video version&lt;/a&gt; for even more details.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>hosting</category>
    </item>
    <item>
      <title>Vercel and Netlify's Convenience Layer: Simplify Your Frontend Workflow</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Wed, 17 Jan 2024 18:52:06 +0000</pubDate>
      <link>https://forem.com/thetombomb/vercel-and-netlifys-convenience-layer-simplify-your-frontend-workflow-5d2e</link>
      <guid>https://forem.com/thetombomb/vercel-and-netlifys-convenience-layer-simplify-your-frontend-workflow-5d2e</guid>
      <description>&lt;p&gt;As a web developer, I've always been on the lookout for hosting services that provide more than just a simple server to host my applications. I wanted a platform that could offer a bunch of additional features that could help me streamline my workflow. This is where Vercel and Netlify come in.&lt;/p&gt;

&lt;p&gt;Both Vercel and Netlify have a lot to offer, and I've been using them for quite some time now. In this article, I want to talk about the convenience layer that both Vercel and Netlify offer, and why I recommend them to anyone looking for frontend hosting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Convenience Layer?
&lt;/h2&gt;

&lt;p&gt;The Convenience Layer refers to a range of services and features that Vercel and Netlify offer to developers to improve your frontend workflow. These platforms offer more than just hosting services. They provide a comprehensive range of development, review, deployment, production, and scaling features. These features go beyond the JavaScript frameworks you are building on like Next.js, React, Astro, etc. &lt;/p&gt;

&lt;p&gt;In fact, Vercel now refers to itself as the Frontend Cloud and Netlify refers to themselves as a Composable Web Platform. Both these names imply they are much more than just a hosting service.&lt;/p&gt;

&lt;p&gt;Let's take a closer look at some of these features that make up the Convenience Layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Development Features
&lt;/h3&gt;

&lt;p&gt;Both Vercel and Netlify offer development features such as &lt;strong&gt;development servers, CLI's, and starter templates&lt;/strong&gt;. These features help developers to quickly set up a new project and start working on it without having to worry about server configurations and other technical details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.netlify.com/integrations/templates"&gt;Netlify Starter Templates&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vercel.com/templates"&gt;Vercel Starter Templates&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Review Feature
&lt;/h3&gt;

&lt;p&gt;Vercel and Netlify also offer a review feature that allows developers to set up &lt;strong&gt;staging servers and automated builds for branches&lt;/strong&gt;. This enables developers to test their code changes before pushing them to production. &lt;/p&gt;

&lt;p&gt;Vercel offers a feature where others can &lt;a href="https://vercel.com/docs/deployments/preview-deployments#comments"&gt;leave comments&lt;/a&gt; directly on the page of preview deployments. Allowing non-technical users to easily provide reviews of your changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DmVYWWb_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tpc88t9h0p3skpfljmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DmVYWWb_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tpc88t9h0p3skpfljmd.png" alt="Demonstrating how you can leave a comment directly in a Vercel Preview branch" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Continuous integration and deployment&lt;/strong&gt; are two critical features that both Vercel and Netlify offer. These features allow developers to automatically deploy their code changes to production without having to worry about manual deployments. The &lt;strong&gt;instant rollback&lt;/strong&gt; in both providers also gives you that safety net should you need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Production Features
&lt;/h3&gt;

&lt;p&gt;Vercel and Netlify also offer a bunch of production features such as &lt;strong&gt;secure environment variables, On-Demand Incremental Static Regeneration, and analytics&lt;/strong&gt;. These features help to protect sensitive data, cache frequently requested pages, and analyze website traffic and user behavior.&lt;/p&gt;

&lt;p&gt;Netlify also exclusively offers &lt;a href="https://docs.netlify.com/site-deploys/split-testing/"&gt;Split Testing&lt;/a&gt;, which lets you divide traffic to your site between different deploys, straight from their Content Delivery Network (CDN)&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling Features
&lt;/h3&gt;

&lt;p&gt;Finally, Vercel and Netlify offer a range of scaling features such as &lt;strong&gt;DDoS protection, caching, content delivery networks (CDN), image optimization, and localization&lt;/strong&gt;. These features help developers to scale their applications and handle large amounts of traffic without any issues.&lt;/p&gt;

&lt;p&gt;Vercel and Netlify can take so much work off your hands with the Convenience layer. Stop worrying about deployment servers, where to store your environment variables, how you'll distribute your application globally. Embrace the convenience layer. &lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario Taking Advantage of the Convenience Layer
&lt;/h2&gt;

&lt;p&gt;Let's take a look at a complicated deployment and hosting scenario that gets cleaned up when the developers embrace Netlify. Keep in mind these same results are achievable in Vercel. &lt;/p&gt;

&lt;h3&gt;
  
  
  Turn This Complicated Workflow:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8qj6GBtM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zshxx0hf8av77476k4ce.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8qj6GBtM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zshxx0hf8av77476k4ce.jpg" alt="Showing a challenging frontend workflow with many disparate services" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Into Something Much Simpler with Netlify:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VMZ6jGg8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/533ax9iso4hjd3gwg4qp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VMZ6jGg8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/533ax9iso4hjd3gwg4qp.jpg" alt="A diagram showing Netlify providing a clean all in one frontend workflow" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consolidate services like development servers, automated builds, CI/CD, CDN, and much more, all into Netlify. This simplifies your tooling so much. With everything in one location you can have faster time to market, faster iterations, and a robust infrastructure powered by Netlify. &lt;/p&gt;

&lt;p&gt;💡Keep in mind this is again all achievable and a similar solution in Vercel. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Vercel and Netlify?
&lt;/h2&gt;

&lt;p&gt;If you're looking for a hosting platform that can offer you more than just a simple server, then Vercel and Netlify are the perfect options for you. With their range of features, you can streamline your frontend development workflow and focus on building great applications without worrying about technical details.&lt;/p&gt;

&lt;p&gt;In conclusion, I highly recommend &lt;a href="https://vercel.com/"&gt;Vercel&lt;/a&gt; and &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt; to anyone looking for frontend hosting services. Try them out today and see for yourself how much they can improve your development workflow.&lt;/p&gt;

&lt;p&gt;Still not convinced? You can check out other Next.js hosting providers in my other article: &lt;a href="https://thetombomb.com/posts/nextjs-hosting-alternatives"&gt;Beyond Vercel: Hosting Alternatives for Next.js&lt;/a&gt; but none of them will compare to the offerings provided by Vercel and Netlify. &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>nextjs</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Beyond Vercel: Hosting Alternatives for Next</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Fri, 12 May 2023 16:53:44 +0000</pubDate>
      <link>https://forem.com/thetombomb/beyond-vercel-hosting-alternatives-for-next-4h5f</link>
      <guid>https://forem.com/thetombomb/beyond-vercel-hosting-alternatives-for-next-4h5f</guid>
      <description>&lt;p&gt;Next.js has gained significant popularity as a frontend framework. And rightly so. Next.js has a solid developer experience, lots of features, and is flexible enough to work for many use cases.  &lt;/p&gt;

&lt;p&gt;And with Next.js comes Vercel, the maintainers of Next.js and the go-to platform for hosting your Next.js applications. You’d think since Vercel built Next.js and continues to add features wouldn’t Vercel be the best hosting solution? &lt;/p&gt;

&lt;p&gt;Yes, Vercel is a great choice, but it’s prudent to understand that there are other hosting options out there that go beyond Vercel. In this article, we will explore alternative hosting solutions for your Next.js app. You need to host your awesome application to show it to the world, so learn where that hosting makes the most sense for you.&lt;/p&gt;

&lt;p&gt;For all the Sitecore Headless Services readers, the hosting options listed below can support your Next.js Headless Services built applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hosting Options
&lt;/h2&gt;

&lt;p&gt;When choosing your hosting consider things like support for advanced Next.js features such as Incremental Static Regeneration (ISR), middleware, and serverless functions. Also, consider the developer experience, costs, and scalability.&lt;/p&gt;

&lt;p&gt;Comparing options for an enterprise setting? Make sure you look into things like security compliance, single sign-on (SSO) integration, and dedicated customer support. &lt;/p&gt;

&lt;p&gt;The two standout alternatives are Netlify and Amazon Web Services (AWS) Amplify. The out-of-the-box support for Next.js features, built-in content delivery network (CDN), and other nice-to-haves of Netlify and AWS Amplify make them great choices. Microsoft’s Azure Static Web Apps is another choice; you can even self-host. Let’s jump into the hosting options.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.netlify.com/with/nextjs/"&gt;Hosting Next.js on Netlify&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V-EVAR_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j95bulblkfd80qimt7zq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V-EVAR_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j95bulblkfd80qimt7zq.png" alt="Netlify Logo" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Netlify deserves its own category because it is the most similar to Vercel. Netlify is one of the most popular web hosting platforms, especially for Jamstack applications. Like Vercel, Netlify can host the most popular frontend frameworks, including Next.js, React, Angular, Nuxt, Vue, and more. &lt;/p&gt;

&lt;p&gt;Netlify has its own content delivery network (CDN), support for Next.js serverless functions, Incremental Static Regeneration (ISR), Middleware, Image Optimization, and more. The Netlify team works hard to provide a fully featured Next.js experience.&lt;/p&gt;

&lt;p&gt;Netlify, in my opinion, is the closest and most worthy competitor to Vercel. For more information check out &lt;a href="https://www.netlify.com/with/nextjs/"&gt;Next.js on Netlify&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.amplify.aws/guides/hosting/nextjs/q/platform/js/"&gt;Next.js with AWS Amplify&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nNyTi6zp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2eki5j4xd91nwglbmc35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nNyTi6zp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2eki5j4xd91nwglbmc35.png" alt="AWS Amplify Logo" width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe you want more control over your deployment workflow, want to stay in your existing cloud environment, need more granular control of your application, or some other reason. You may find yourself considering &lt;a href="https://aws.amazon.com/amplify/"&gt;AWS Amplify&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;AWS Amplify provides a complete solution for hosting a globally distributed Next.js application. It supports all the biggest Next.js features, including SSR, API routes, middleware, ISR, and image optimization. Meaning less infrastructure setup and maintenance for you. The developer experience is not as seamless as Vercel or Netlify, but I see improvements being made.&lt;/p&gt;

&lt;p&gt;Find their Next.js hosting tutorial here: &lt;a href="https://aws.amazon.com/blogs/mobile/amplify-next-js-13/"&gt;Deploy a Next.js 13 app to AWS with Amplify Hosting&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Vercel, Netlify, and AWS Amplify are my recommendations for hosting Next.js. They all have purpose-built solutions for hosting globally distributed Next.js apps and support the best features of Next.js. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://azure.microsoft.com/en-us/products/app-service/static"&gt;Microsoft Azure Static Web Apps&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0e58LBEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cj22wkry8cd63n1x3499.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0e58LBEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cj22wkry8cd63n1x3499.png" alt="Azure Static Web Apps Logo" width="238" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know many people are in the Microsoft Cloud ecosystem, so I want to mention the Microsoft solution Azure Static Web Apps. &lt;/p&gt;

&lt;p&gt;You may have noticed Static Web Apps is not currently one of my recommended hosting platforms. It does not &lt;em&gt;currently&lt;/em&gt; support many of Next.js’ more advanced features. There is a public preview available that claims support for zero-config setup, SSR, ISR, API Routes, Image optimization, and more. But I would not consider this public preview ready for production enterprise Next.js apps. &lt;/p&gt;

&lt;p&gt;Hopefully, in the future, when no longer in preview, I can add Azure Static Web Apps as a recommendation for Next.js hosting. For now, it’s better to hold off.&lt;/p&gt;

&lt;p&gt;Here is a recent video detailing the public preview: &lt;a href="https://www.youtube.com/watch?v=68CFn-EkkNM"&gt;Enhanced Hybrid Next.js Support in Azure Static Web Apps&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dedicated Node.js Hosting &amp;amp; Self-Hosting Next.js
&lt;/h2&gt;

&lt;p&gt;The last hosting option is dedicated Node.js Hosting and Self-Hosting. This is only for when you need complete control of your Next.js application and also want full responsibility for the maintenance. I stay very far away from this because I do not want to maintain my own CDN, I don’t want to deal with all the infrastructure, and I don’t want to set EVERYTHING up. &lt;/p&gt;

&lt;p&gt;The platforms you may use if you are in this category could be an AWS EC2 instance, Digital Ocean, Heroku, or, heck, it could be your own laptop. At its most basic, the workflow here is that you would run &lt;code&gt;next build&lt;/code&gt; to generate the static HTML files. Then host them on the platform of your choice. &lt;/p&gt;

&lt;p&gt;Don’t make things harder for yourself than they need to be. Consider your top three options Vercel, Netlify, and AWS Amplify. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;While Vercel is an exceptional choice for hosting Next.js applications, it's essential to recognize that alternative options are available to suit your specific needs and preferences. Determine what is most important to you and your situation, then choose what fits best.&lt;/p&gt;

&lt;p&gt;Support for advanced Next.js features, developer experience, and not having to maintain a globally distributed infrastructure are most important to me. That’s why I have recommended Netlify and AWS Amplify as alternatives to Vercel. Choose any of the three, and you’ll have a fast, secure, and scalable Next.js app. Vercel, Netlify, and AWS Amplify can all support a Sitecore JSS at an enterprise scale. &lt;/p&gt;

&lt;p&gt;If you do choose one of these three or even something else, reach out to me and let me know why you made your decision.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>jamstack</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Next.js App Directory Architecture First Impressions</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Mon, 06 Mar 2023 19:52:57 +0000</pubDate>
      <link>https://forem.com/thetombomb/nextjs-app-directory-architecture-first-impressions-437g</link>
      <guid>https://forem.com/thetombomb/nextjs-app-directory-architecture-first-impressions-437g</guid>
      <description>&lt;p&gt;Thomas Desmond here, Developer Advocate at Sitecore. Recently I’ve been intrigued by the new Next.js &lt;code&gt;app&lt;/code&gt; directory architecture released in beta with Next.js 13.1. So I set out to build a proof-of-concept app trying out the new architecture in Next.js. &lt;/p&gt;

&lt;p&gt;I decided to build a clone of the Vercel Commerce app using &lt;a href="https://ordercloud.io/"&gt;Sitecore OrderCloud&lt;/a&gt; and the new architecture. I want to give my early impressions of the new architecture and talk about documentation, shifting your mindset to &lt;a href="https://thetombomb.com/posts/react-server-components-nextjs"&gt;Server Components&lt;/a&gt; versus &lt;a href="https://thetombomb.com/posts/use-client-nextjs"&gt;Client Components&lt;/a&gt;, package support, and lastly, should you migrate to the new architecture.  &lt;/p&gt;

&lt;p&gt;Let’s jump in!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Documentation
&lt;/h2&gt;

&lt;p&gt;I started my journey into the app directory architecture by reading the documentation. It excited me to see what was possible with the new architecture in Next.js. It was well thought out. And it even uses Vercel’s new page preview feature where visitors can leave comments directly on the page, and you can see your and others’ comments. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tIquG4lS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c2c7puiytf8ap6huo07k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tIquG4lS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c2c7puiytf8ap6huo07k.png" alt="Able to leave public comments directly in the Vercel documentation" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was super helpful because it added clarity to certain sections or you could directly comment about support for different features.&lt;/p&gt;

&lt;p&gt;I’d like to add that the documentation is positioned well for someone transitioning from pages-based architecture—lots of comparing old versus new. &lt;/p&gt;

&lt;p&gt;To close out documentation, I’d like to add that since this is a very new and BIG change to Next.js. There is not a lot of community documentation…yet (blog posts, videos, tutorials, starter kits). You will likely read GitHub issue threads if you encounter something new or unexpected. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Server Components vs. Client Components
&lt;/h2&gt;

&lt;p&gt;One of the biggest changes in the new app directory is that all components are &lt;a href="https://thetombomb.com/posts/react-server-components-nextjs"&gt;Server Components&lt;/a&gt; by default. A server component is a component that renders entirely on the server—leveraging the power of the server to fetch data and reduce dependency requirements for the client. &lt;/p&gt;

&lt;p&gt;Ideally, you use Server Components as much as possible to reduce the load on the client. So you want to think with Server Components in mind. &lt;/p&gt;

&lt;p&gt;Server Components are great, but they can’t do everything. Specifically, they cannot contain client interactivity. A component built and rendered by the server cannot contain client code. For example, &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt;, &lt;code&gt;onClick&lt;/code&gt; all cannot exist inside a Server Component. &lt;/p&gt;

&lt;p&gt;Next.js does a great job of showing you an error if these sneak their way into one of your Server Components, but you’ll learn quickly what can and cannot be done in a Server Component. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7q7UrZFR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ugdy8kdgxjk2iyd1gdk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7q7UrZFR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ugdy8kdgxjk2iyd1gdk.png" alt="Error displayed when using client only code in a component without the use client directive" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s easy enough to tell a component that it is a Client Component with the new &lt;code&gt;use client&lt;/code&gt; directive that you add to the top of your file. This tells Next.js that this component has client interactivity and needs to be a Client Component. The functionality of a Client Component is that it is pre-rendered on the server and then hydrated on the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="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="nx"&gt;Counter&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActive&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="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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    // Your code here
    &lt;span class="p"&gt;&amp;lt;/&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;At first, I thought putting &lt;code&gt;use client&lt;/code&gt; in many of my files indicated I was doing something wrong. But in the previous &lt;code&gt;pages&lt;/code&gt; architecture, everything was a Client Component. So it may just be that I am a little used to the old architecture and not fully thinking with my Server Component hat yet.  &lt;/p&gt;

&lt;p&gt;But some of the packages and libraries I like to use in Next.js require using Client Components, which was a big reason for me having the &lt;code&gt;use client&lt;/code&gt; in many files. &lt;/p&gt;

&lt;p&gt;So that leads me to Package Support&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Package Support
&lt;/h2&gt;

&lt;p&gt;A new architecture is a serious change. This is a breaking change for some packages and libraries. &lt;/p&gt;

&lt;p&gt;An early difficulty I encountered was using UI component libraries like &lt;a href="https://mantine.dev/"&gt;Mantine&lt;/a&gt; and &lt;a href="https://mui.com/"&gt;Material UI&lt;/a&gt; in the new architecture. After looking through some GitHub issues, the culprit is &lt;a href="https://emotion.sh/"&gt;Emotion&lt;/a&gt;, a package many component libraries rely on that does not support server rendering. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x3cZB8rp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wc8c65wu1jnwninctj6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x3cZB8rp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wc8c65wu1jnwninctj6v.png" alt="Mantine and Material UI logos, two React component libraries" width="834" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a custom initialization setup, I did get Mantine working for my Client Components. But that meant any component with UI was going to be Client Components, not taking advantage of those Server Component benefits. &lt;/p&gt;

&lt;p&gt;It’s unclear if Emotion will or can ever support being Server Rendered, but they are aware of the problem and have issues open tracking how they want to move forward. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mantinedev/mantine/issues/2815"&gt;Mantine with Next.js 13 app dir Issue #2815&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/emotion-js/emotion/issues/2928"&gt;Emotion: Plans to support Next.js 13 - /app directory Issue #2928&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was the only major package support hurdle I had to take on, but it did take custom code, and even the Mantine team says it’s not fully tested or supported in its current state. &lt;/p&gt;

&lt;p&gt;Bringing in simpler packages that didn’t require setup or initialization worked out of the box, so most of your packages and libraries should be supported. However, it’s worth checking with the developers or maintainers to see if the new app directory is supported. &lt;/p&gt;

&lt;p&gt;It’s worth noting that currently, the recommended UI styling choice for the app directory is to use CSS or tools that generate CSS like Tailwind. Component libraries like Mantine and Material UI do not take full advantage of new &lt;code&gt;app&lt;/code&gt; directory features. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Migrate now or later?
&lt;/h2&gt;

&lt;p&gt;Finally, we are at the question. Should you migrate to the new architecture?  &lt;/p&gt;

&lt;p&gt;The short answer is no&lt;/p&gt;

&lt;p&gt;At the time the app directory architecture is still in beta and not recommended for production. &lt;/p&gt;

&lt;p&gt;But if you are a Next.js user and plan to continue using Next.js, I think it’s a good idea to start poking around and experimenting with the new architecture. Maybe build a small side project with it to get a feel for it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Or the page architecture and app architecture can work together&lt;/strong&gt;. It’s not one or the other. So you could consider building out your next feature in the app directory. Keep all your existing app functionality in the pages directory but get a feel for the app directory changes by building a new feature. &lt;/p&gt;

&lt;p&gt;Overall I like the new architecture. It looks like it will allow for more options when building your pages and components to mix and match static versus dynamic content. It’s a big change for Next.js but a step forward in allowing you to do more.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>jamstack</category>
    </item>
    <item>
      <title>Client Components and use client in Next.js App Directory</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Thu, 02 Feb 2023 20:31:41 +0000</pubDate>
      <link>https://forem.com/thetombomb/client-components-and-use-client-in-nextjs-app-directory-5738</link>
      <guid>https://forem.com/thetombomb/client-components-and-use-client-in-nextjs-app-directory-5738</guid>
      <description>&lt;p&gt;Are you considering using the latest Next.js 13 feature, the new &lt;code&gt;app&lt;/code&gt; folder-based architecture? Finding yourself adding the &lt;code&gt;use client&lt;/code&gt; directive in lots of files? Or hitting this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: 

You're importing a component that needs useEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

   ,----
 1 | import { useEffect  } from 'react';
   :                                                                                          ^^^^^^
   `---- 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, every component in the Next.js &lt;code&gt;app&lt;/code&gt; directory will be a Server Component. Server Components are excellent. There are many reasons for them to be the default, but now you must explicitly tell Next.js when you have a component that needs client interactivity. Not everything can be done sever-side. That’s where Client Components come in. &lt;/p&gt;

&lt;h2&gt;
  
  
  Declaring a Client Component
&lt;/h2&gt;

&lt;p&gt;To fix the above error, you must make your component a Client Component. To declare a Client Component, you add the &lt;code&gt;use client&lt;/code&gt; directive to the top of the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="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;Counter&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    // Your code here
    &lt;span class="p"&gt;&amp;lt;/&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;The component above requires &lt;code&gt;use client&lt;/code&gt; because it has &lt;code&gt;useState&lt;/code&gt; in it. The state cannot be handled server-side. Other common reasons to have &lt;code&gt;use client&lt;/code&gt; would be if your component uses &lt;code&gt;useEffect&lt;/code&gt;, &lt;code&gt;useRef&lt;/code&gt;, or &lt;code&gt;onClick&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Depending on your application requirements, you may add &lt;code&gt;use client&lt;/code&gt; to several of your components. Adding &lt;code&gt;use client&lt;/code&gt; is okay, but it is good to understand what adding &lt;code&gt;use client&lt;/code&gt; does to your components. &lt;/p&gt;

&lt;h2&gt;
  
  
  What does &lt;code&gt;use client&lt;/code&gt; do in Next.js?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Adding the &lt;code&gt;use client&lt;/code&gt; directive turns a component into a Client Component.&lt;/strong&gt; A component must be a Client Component if it requires client-side interactivity (useState, OnClick, etc). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 The Next.js documentation states: You can think of Client Components as how Next.js 12 and previous versions worked (i.e. the &lt;code&gt;pages/&lt;/code&gt; directory). &lt;a href="https://beta.nextjs.org/docs/rendering/server-and-client-components#client-components" rel="noopener noreferrer"&gt;https://beta.nextjs.org/docs/rendering/server-and-client-components#client-components&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How is a Client Component rendered?
&lt;/h2&gt;

&lt;p&gt;A Client Component is pre-rendered on the server and hydrated on the client. Now, this is where I needed clarification, so I did the research and wrote this article. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;What does it mean to be pre-rendered on the server and hydrated on the client? Are client components only rendered partially client-side?&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-rendering vs. Hydration in Next.js
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pre-rendering&lt;/strong&gt; is when HTML is generated in advance (server-side or during build time) with minimal JavaScript. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hydration&lt;/strong&gt; occurs once the page gets loaded into the browser.  JavaScript gets executed, and your component becomes interactive. &lt;/p&gt;

&lt;p&gt;So a Client Component isn’t entirely client-side. Next.js tries to do as much work as possible in the pre-rendering step to alleviate the work required client-side. Pre-rendering the HTML in advance without interactivity. Then, hydrate that HTML structure with the event handlers and interactivity. &lt;/p&gt;

&lt;p&gt;There are two forms of pre-rendering in Next.js: Static and Server-Side. Static or Server-Rendered is determined by how you fetch your data in Next.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;staticPreRendering&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="s2"&gt;`https://...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;force-cache&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;serverPreRendering&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="s2"&gt;`https://...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before the Next.js 13 &lt;code&gt;app&lt;/code&gt; directory architecture, the pre-rendering method was determined by &lt;code&gt;getStaticProps&lt;/code&gt; or &lt;code&gt;getServerSideProps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can learn more about how data fetching has changed in Next.js 13 in a previous post of mine &lt;a href="https://thetombomb.com/posts/nextjs-app-architecture" rel="noopener noreferrer"&gt;3 Big Changes in The New Next.js App Folder Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does having &lt;code&gt;use client&lt;/code&gt; mean I’m using Next.js 13 wrong?
&lt;/h2&gt;

&lt;p&gt;No. &lt;/p&gt;

&lt;p&gt;Before the new app directory architecture, every component was a Client Component. Now that Server Components have been introduced, the distinction between Client Components and Server Components is essential, but having Client Components does not mean you are using Next.js 13 wrong. &lt;/p&gt;

&lt;p&gt;Try to use Server Components as much as possible in your application. One benefit is that they help reduce the amount of JavaScript required on the client, thus speeding up performance. The best way to ensure you use Sever Components is to build small single-purpose components. Single-purpose components will help you separate components needing client-side interactivity and those not.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 For more on why you should use Server Components whenever possible, check out: &lt;a href="https://thetombomb.com/posts/react-server-components-nextjs" rel="noopener noreferrer"&gt;What and Why: React Server Components in Next.js 13&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Building with the new Next.js 13 &lt;code&gt;app&lt;/code&gt; directory architecture means you must learn to use the &lt;code&gt;use client&lt;/code&gt; directive. Having &lt;code&gt;use client&lt;/code&gt; in your application is inevitable. I cannot imagine having a real-world application built with Next.js that does not need &lt;code&gt;useState&lt;/code&gt; or &lt;code&gt;useEffect&lt;/code&gt; in a component.&lt;/p&gt;

&lt;p&gt;If you put &lt;code&gt;use client&lt;/code&gt; in every component, you may need to reconsider your architecture and separate your components more. &lt;/p&gt;

&lt;p&gt;Want more content about the new Next.js 13 architecture? Check out &lt;a href="https://thetombomb.com/posts/nextjs-app-architecture" rel="noopener noreferrer"&gt;3 Big Changes in The New Next.js App Folder Architecture&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>crypto</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>3 Big Changes in The New Next.js App Folder Architecture</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Tue, 17 Jan 2023 17:45:53 +0000</pubDate>
      <link>https://forem.com/thetombomb/3-big-changes-in-the-new-nextjs-app-folder-architecture-2dgm</link>
      <guid>https://forem.com/thetombomb/3-big-changes-in-the-new-nextjs-app-folder-architecture-2dgm</guid>
      <description>&lt;p&gt;With Next.js 13 the &lt;code&gt;app/&lt;/code&gt; folder architecture was released in beta. The goal with the architecture is to make Next.js development easier, faster, and ship less JavaScript to the client. &lt;/p&gt;

&lt;p&gt;The new architecture is a big change to Next.js as it changes how you architect your application from the ground up. Luckily, the traditional &lt;code&gt;page/&lt;/code&gt; folder based architecture is still supported and will likely still be supported for a while. &lt;/p&gt;

&lt;p&gt;However, it’s important to look at what the future of Next.js looks like. So let’s cover the 3 biggest changes you want to be aware of in the new Next.js &lt;code&gt;app/&lt;/code&gt; folder-based architecture. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Component Rendering&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Fetching&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Routing&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The changes to these three categories will be the focus of the article. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❗ &lt;strong&gt;Important:&lt;/strong&gt; Next.js 13 still supports the previous architecture with all pages in the &lt;code&gt;pages/&lt;/code&gt; directory. And actually as of right now the new &lt;code&gt;app/&lt;/code&gt; based architecture is still in beta and not recommended for production. It is currently possible and I would encourage using the &lt;code&gt;pages/&lt;/code&gt; and &lt;code&gt;app/&lt;/code&gt; architectures side by side. &lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Before jumping into the 3 big changes let’s first cover the biggest change: The Architecture itself. The big change is that your application will now be built inside an &lt;code&gt;app/&lt;/code&gt; folder. As I have mentioned you could continue to build and use what you have in your &lt;code&gt;pages/&lt;/code&gt; folder. But if you are building new features and on the latest version of Next.js consider moving to the &lt;code&gt;app/&lt;/code&gt; folder. The &lt;code&gt;pages&lt;/code&gt; and &lt;code&gt;app&lt;/code&gt; architecture were designed to be used in conjunction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&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;js&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;  &lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;  &lt;span class="err"&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;js&lt;/span&gt;
&lt;span class="nx"&gt;node_modules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="kr"&gt;public&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the &lt;code&gt;app/&lt;/code&gt; folder is where you get access to all the new features of Next.js 13. It may seem like a daunting task to re-architect your application but becoming familiar with the changes is the first step. &lt;/p&gt;

&lt;h2&gt;
  
  
  Component Rendering
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;By default, the &lt;code&gt;app/&lt;/code&gt; directory uses Server Components.&lt;/strong&gt; The biggest reason for this is that the more you can render on the server the less JavaScript needs to be sent to the client &lt;/p&gt;

&lt;p&gt;The server has limitations that the client does not and vice versa, so you can still create client-side components in Next.js. If you need access to things like &lt;code&gt;useState&lt;/code&gt; or &lt;code&gt;useEffect&lt;/code&gt; that will need to be a client component. You declare a client component by adding &lt;code&gt;'use client'&lt;/code&gt; at the top of your component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="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;Counter&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    // Your code here
    &lt;span class="p"&gt;&amp;lt;/&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;So you will be mixing and matching server with client components in your application. Server components are the default and thus should be used whenever possible. This encourages &lt;a href="https://dev.to/posts/component-driven-design"&gt;component-driven development&lt;/a&gt;. Ensuring that you separate logic that requires the client and the logic that can be executed on the server. &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%2F99h7do49wf81dcq9vtwu.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%2F99h7do49wf81dcq9vtwu.png" alt="Mixing client and server components in the component tree" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m excited about this feature and looking forward to leveraging the server more. I do think it adds complexity as you will need to design with a server vs client approach. Don’t take the easy way out and mark everything as &lt;code&gt;use client&lt;/code&gt; and lose out on all the server-side benefits.&lt;/p&gt;

&lt;p&gt;This change will require some getting used to if you are coming from the traditional Next.js architecture but the improvements Server Components can provide are worth the effort. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Want to learn more about Server Components?&lt;/strong&gt; Check out this previous article: &lt;a href="https://thetombomb.com/posts/react-server-components-nextjs" rel="noopener noreferrer"&gt;What and Why: React Server Components in Next.js&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://beta.nextjs.org/docs/rendering/fundamentals" rel="noopener noreferrer"&gt;Next.js Documentation on Rendering Fundamentals&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Fetching
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The new architecture simplifies data fetching by moving to a more standard &lt;code&gt;async/await&lt;/code&gt; approach using the &lt;code&gt;fetch()&lt;/code&gt; API. This means no more &lt;code&gt;getServerSideProps&lt;/code&gt; or &lt;code&gt;getStaticProps&lt;/code&gt;.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This also allows you to fetch the data you need at the component level. This is a big improvement in Next.js. No more fetching at the page level and passing data deep down different component layers. Fetch the data when and where you need it.&lt;/p&gt;

&lt;p&gt;So now when it comes to building a page in Next.js you don’t need to first ask: “Will this page be static or dynamic?” You now have the ability to mix and match dynamic and static components in a single page.&lt;/p&gt;

&lt;p&gt;Whether a component is dynamic or static is determined by a &lt;code&gt;cache&lt;/code&gt; property on your &lt;code&gt;fetch()&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;force-cache&lt;/code&gt;: The default and will generate a static page, the equivalent of &lt;code&gt;getStaticProps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;no-store&lt;/code&gt;: Data will be fetched with each request, the equivalent of &lt;code&gt;getServerSideProps&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="k"&gt;async&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="c1"&gt;// This request should be cached until manually invalidated.&lt;/span&gt;
  &lt;span class="c1"&gt;// Similar to `getStaticProps`.&lt;/span&gt;
  &lt;span class="c1"&gt;// `force-cache` is the default and can be omitted.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;staticData&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="s2"&gt;`https://...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;force-cache&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 request should be refetched on every request.&lt;/span&gt;
  &lt;span class="c1"&gt;// Similar to `getServerSideProps`.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamicData&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="s2"&gt;`https://...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-store&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 request should be cached with a lifetime of 10 seconds.&lt;/span&gt;
  &lt;span class="c1"&gt;// Similar to `getStaticProps` with the `revalidate` option.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;revalidatedData&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="s2"&gt;`https://...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last &lt;code&gt;fetch()&lt;/code&gt; example in the code above shows how Incremental Static Regeneration can be achieved with the new fetch() paradigm. &lt;/p&gt;

&lt;p&gt;This change of using fetch() instead of &lt;code&gt;getServerSideProps&lt;/code&gt; and &lt;code&gt;getStaticProps&lt;/code&gt; is not a huge change but you will have to adapt to the new syntax and structure when fetching your data. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://beta.nextjs.org/docs/data-fetching/fundamentals" rel="noopener noreferrer"&gt;Next.js Documentation on Data Fetching&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Routing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Routing has been improved with support for layouts, nested routing, loading states, error states, and more.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The new routing strategy builds upon the file system-based routing previously available. So what's inside your &lt;code&gt;app/&lt;/code&gt; folder determines your routes but now there are more special files that determine the UI for your route. &lt;em&gt;Note: I am using the &lt;code&gt;.js&lt;/code&gt; file extension but &lt;code&gt;.ts&lt;/code&gt;, &lt;code&gt;.jsx&lt;/code&gt;, or &lt;code&gt;.tsx&lt;/code&gt; are also valid.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;page.js:&lt;/strong&gt; Required for every route. Defines the UI and makes the path publicly accessible. Here is where you will bring all the components together to form your page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;layout.js&lt;/strong&gt;: Required at the root level. Used to define the UI across multiple pages. A great example would be your navigation bar. A neat feature is that layouts preserve state and do not re-render if the page you route to has the same layout. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;loading.js:&lt;/strong&gt; Optional displayed when a loading state is active for the page. Used in conjunction with React Suspense to show loading states.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;error.js:&lt;/strong&gt; Optional gives you the ability to isolate errors and choose what to show if an error does occur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;head.js:&lt;/strong&gt; Optional in this file you define what you want in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So for each route, you need a page.js file. The layout.js is required only at the root but can be left out of subsequent routes. The others are there to enhance reusability and separate concerns. Below is a possible routing structure inside your app/ folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&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;js&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;  &lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;  &lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;  &lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can store components, styles, tests, or really anything else in the routing folder structure as long as they do not conflict with the special file names in Next.js.&lt;/p&gt;

&lt;p&gt;Hopefully, this change does not cause too many issues for you if you are migrating from traditional Next.js architecture. You will need to embrace the new &lt;code&gt;page.js&lt;/code&gt; naming convention and possibly move logic around for your loading and error-handling states. This does provide a better separation between your page's different states. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://beta.nextjs.org/docs/routing/fundamentals" rel="noopener noreferrer"&gt;&lt;em&gt;Next.js Documentation on Routing&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;So the big changes happening in the new Next.js &lt;code&gt;app/&lt;/code&gt; folder-based architecture are how you do component rendering, data fetching, and routing in your applications. With the focus on leveraging the server as much as possible. &lt;/p&gt;

&lt;p&gt;The new rendering process should help reduce the amount of JavaScript required by the client, leading to faster sites. The new data fetching process is more in line with standard React data fetching practices and allows for fetching at a component level. Routing doubles down on the file-system-based routing and supports new Server Components push in the new architecture.&lt;/p&gt;

</description>
      <category>help</category>
      <category>webdev</category>
      <category>softwaredevelopment</category>
      <category>security</category>
    </item>
    <item>
      <title>Accessing JWT and Session Data in NextAuth.js with Callbacks (Okta Example)</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Tue, 03 Jan 2023 19:23:57 +0000</pubDate>
      <link>https://forem.com/thetombomb/accessing-jwt-and-session-data-in-nextauthjs-with-callbacks-okta-example-159l</link>
      <guid>https://forem.com/thetombomb/accessing-jwt-and-session-data-in-nextauthjs-with-callbacks-okta-example-159l</guid>
      <description>&lt;p&gt;Do you have NextAuth.js working in your Next.js app but need to extend the functionality with callbacks? You are in the right place. In this article, I’ll show you how NextAuth.js provides callbacks to give you greater control of your authentication. You will see examples with JSON Web Tokens (JWT) and Session callbacks, and these translate well to the other callbacks available in NextAuth.js. I’ll be showing off with Okta as the auth provider, but if you are using a different provider you’ll benefit from this as well. &lt;/p&gt;

&lt;p&gt;If you are still setting up NextAuth.js, you can follow my previous post, &lt;a href="https://thetombomb.com/posts/nextjs-nextauth-okta"&gt;Adding Authentication to Nextjs with NextAuth.js and Okta&lt;/a&gt;. It uses Okta as well for the examples but is generic enough to help you set up for any provider. &lt;/p&gt;

&lt;h2&gt;
  
  
  Callbacks in NextAuth.js
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://next-auth.js.org/configuration/callbacks"&gt;Callbacks are asynchronous functions&lt;/a&gt; that NexAuth.js exposes so that you can execute your own logic when an action is performed. Each callback has specific criteria for when it will run covered below.&lt;/p&gt;

&lt;p&gt;There are 4 callbacks that you have access to and we will be focusing on the top 2.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JWT callback&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Session callback&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Sign in callback&lt;/li&gt;
&lt;li&gt;Redirect callback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You access these callbacks and write your logic in the &lt;code&gt;pages/api/auth/[...nextauth].ts&lt;/code&gt; file. Below is a code example with empty JWT and session callbacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/api/auth/[...nextauth].ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NextAuth&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;next-auth&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;authOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Configure one or more authentication providers&lt;/span&gt;
    &lt;span class="na"&gt;providers&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="na"&gt;session&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="na"&gt;secret&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;SECRET&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;callbacks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;token&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;any&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;async&lt;/span&gt; &lt;span class="nx"&gt;session&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="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;any&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="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;NextAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The JSON Web Token (JWT) Callback
&lt;/h2&gt;

&lt;p&gt;This callback is called whenever a JWT is created or updated. The return value will be &lt;strong&gt;encrypted&lt;/strong&gt; and stored in the client machine's cookie information. You are likely using the JWT to authenticate with another service so let’s take a look at how you can access and decrypt your JWT.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/api/auth/[...nextauth].ts&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;callbacks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;token&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;any&lt;/span&gt;&lt;span class="p"&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;account&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&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;access_token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idToken&lt;/span&gt; &lt;span class="o"&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;id_token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oktaId&lt;/span&gt; &lt;span class="o"&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;providerAccountId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="c1"&gt;// Decrypting JWT to check if expired&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;tokenParsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&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;dateNowInSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&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;dateNowInSeconds&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;tokenParsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&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;expired token&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;token&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;First, you validate if the &lt;code&gt;account&lt;/code&gt; exists. The account refers to the authentication provider, which in my case is Okta. It then takes the required account information and stores that in the token. You can debug or &lt;code&gt;console.log&lt;/code&gt; to see what all information is available for your provider in the &lt;code&gt;account&lt;/code&gt; variable.  &lt;/p&gt;

&lt;p&gt;Second, the token is decrypted so you can check the expiration. If the token is expired an error is thrown. You may want a more delicate solution but this gives you the groundwork for decrypting and checking values in the JWT callback.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 The above code has Okta-specific provider variables. The information accessed from the &lt;code&gt;account&lt;/code&gt; variable is going to be information about the user's Okta account. If you are using different providers it’s important to verify the naming conventions used by your provider. For example, &lt;code&gt;id_token&lt;/code&gt; may be &lt;code&gt;idToken&lt;/code&gt; instead. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://next-auth.js.org/configuration/callbacks#jwt-callback"&gt;NextAuth.js JWT Callback Documentation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Session Callback Example
&lt;/h2&gt;

&lt;p&gt;The session callback is called whenever a session is checked. So any calls to &lt;code&gt;getSession()&lt;/code&gt;, &lt;code&gt;useSession()&lt;/code&gt;, &amp;amp; &lt;code&gt;/api/auth/session&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Inside the session callback, you can extend what data is returned to you whenever the session is checked. In my use case, I needed the user's &lt;code&gt;oktaId&lt;/code&gt; passed through so I did that in the session callback.&lt;/p&gt;

&lt;p&gt;The example below shows taking information from the token and passing that along to the session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/api/auth/[...nextauth].ts&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;callbacks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;session&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="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessToken&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="nx"&gt;idToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idToken&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="nx"&gt;oktaId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oktaId&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;session&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="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;a href="https://next-auth.js.org/configuration/callbacks#session-callback"&gt;NextAuth.js Session Callback Documentation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;When adding authentication to your Next.js app with NextAuth.js it’s likely you will need to use the callback feature if you want to go beyond the most basic implementation. This was definitely the most confusing and difficult part for me but I hope the code samples are useful in your auth implementation!&lt;/p&gt;

&lt;p&gt;To learn more check the &lt;a href="https://next-auth.js.org/configuration/callbacks"&gt;Callback Docs&lt;/a&gt; page provided by NextAuth.js or reach out to me and I’d love to learn more about your project and help out. If you need help getting your initial setup of NextAuth.js working read my previous blog: &lt;a href="https://thetombomb.com/posts/nextjs-nextauth-okta"&gt;Adding Authentication to Nextjs with NextAuth.js and Okta&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>authentica</category>
      <category>okta</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What and Why: React Server Components in Next.js 13</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Thu, 10 Nov 2022 18:03:40 +0000</pubDate>
      <link>https://forem.com/thetombomb/what-and-why-react-server-components-in-nextjs-13-1dki</link>
      <guid>https://forem.com/thetombomb/what-and-why-react-server-components-in-nextjs-13-1dki</guid>
      <description>&lt;p&gt;React Server Components are now fully supported in Next.js. &lt;a href="https://nextjs.org/blog/next-13"&gt;Next.js 13 was recently released&lt;/a&gt; and React Server Components move out of experimental into full support. I would go beyond saying Next.js supports them to Next.js is heavily pushing for the use of React Server Components.&lt;/p&gt;

&lt;p&gt;Next.js 13 introduced &lt;code&gt;app&lt;/code&gt; directory architecture which is an entirely new way to architect your Next.js applications with React Server Components in mind. The default for components built under the app directory are React Server Components, you must explicitly add &lt;code&gt;use client&lt;/code&gt; if you want to build a client-side component. &lt;/p&gt;

&lt;p&gt;It’s okay if you have never heard of React Server Components. They only came into existence in December 2020 and so far are not widely used. Let’s look into React Server Components and why the Next.js team wants you to use them by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a React Server Component?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A React Server Component is a component that renders on the server.&lt;/strong&gt; React Server Components leverage the server's power to provide a more predictable and performant experience for your visitors. &lt;/p&gt;

&lt;p&gt;The most common use case for a Server Component would be to fetch data and render your component based on that data all on the server.&lt;/p&gt;

&lt;p&gt;Things that you’ll want to consider putting in a Server Component would be: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetching data (take advantage of the server's super speedy connection)&lt;/li&gt;
&lt;li&gt;Accessing backend resources or filesystem&lt;/li&gt;
&lt;li&gt;Components with large dependencies that do not need client-side interactivity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;React Server Components cannot include any client-side interactivity&lt;/strong&gt;, this means your app will most likely contain a mix of server components and client-side components. This adds complexity as you’ll need to think ahead of how you want to best distribute components, but the goal is to move as much to the server where things are predictable and more performant. &lt;/p&gt;

&lt;p&gt;Common examples of client-side only calls: &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt;, &lt;code&gt;onClick&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do you want React Server Components?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The number 1 reason is Server Components contribute zero to the overall bundle size of your application.&lt;/strong&gt; This means smaller download sizes for visitors, leading to your page becoming available faster. &lt;/p&gt;

&lt;p&gt;This benefit can be extremely helpful if you have packages you need to use but do not need them client side. Keeping those dependencies completely server-side means reduced downloads for the client. For example, I use an npm package for this blog to convert my &lt;code&gt;.mdx&lt;/code&gt; files to HTML. That could be a completely server-side process, removing that package from the bundle downloaded by the client.&lt;/p&gt;

&lt;p&gt;As mentioned above, another big benefit is that your code is running on a powerful server, hopefully, closer to your data as well. Pushing compute to the server can make a big difference for your visitors on a mobile device. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started with React Server Components?
&lt;/h2&gt;

&lt;p&gt;If you want to build with React Server Components upgrade to Next.js 13 or use &lt;code&gt;create-next-app&lt;/code&gt; to start a new app and build with the new &lt;code&gt;app/&lt;/code&gt; based architecture.  &lt;/p&gt;

&lt;p&gt;Components built with the new &lt;a href="https://nextjs.org/blog/next-13#server-components"&gt;Next.js 13 app folder-based architecture&lt;/a&gt; will be React Server Components by default. The new architecture is still in beta but I expect it to become recommended practice soon. The goal of this new architecture is to reduce the amount of JavaScript sent to the client. &lt;/p&gt;

&lt;p&gt;Don’t worry though the original &lt;code&gt;pages/&lt;/code&gt; based architecture that has been used in all prior versions of Next.js is still supported in version 13 as well. You can incrementally adopt the new architecture. &lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Next.js Authentication with Okta and NextAuth.js 4.0</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Wed, 19 Oct 2022 21:19:56 +0000</pubDate>
      <link>https://forem.com/thetombomb/nextjs-authentication-with-okta-and-nextauthjs-40-481p</link>
      <guid>https://forem.com/thetombomb/nextjs-authentication-with-okta-and-nextauthjs-40-481p</guid>
      <description>&lt;p&gt;Looking to add authentication to your Next.js application? Considering Okta as your login provider? You have come to the right place! This article covers adding authentication to your Next.js application with &lt;a href="https://next-auth.js.org/"&gt;NextAuth.js&lt;/a&gt; and using Okta as a login provider. All with TypeScript in mind along the way. &lt;/p&gt;

&lt;p&gt;If you don’t want to use Okta that’s fine, skip to section 3 to see how to use NextAuth.js with any properly configured provider. &lt;/p&gt;

&lt;p&gt;Here’s the &lt;a href="https://github.com/thomas-desmond/nextjs-nextauth-okta"&gt;GitHub repository&lt;/a&gt; where I have all the code mentioned in this article. Also, I think it’s important to note the package versions that this article has been tested against: next 12.3.0, next-auth 4.13.0, react 18.2.0&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create A Brand New Next.js App and Install NextAuth.js
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx create-next-app --ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates a brand new Next.js application for us and the &lt;code&gt;--ts&lt;/code&gt; means the starter app will be initialized with TypeScript. Go through the options, name your app, and you’ll have a brand new Next.js app with TypeScript!&lt;/p&gt;

&lt;p&gt;Change directories into your new app and the first thing you’ll do is install NextAuth.js. The package is called &lt;code&gt;next-auth&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i next-auth@4.13.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I’ve put the explicit &lt;code&gt;@4.13.0&lt;/code&gt; because that’s the latest version that I have tested for this article. I assume any 4.0 version will work but I wanted you to be aware of what I have explicitly tested against.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;What is NextAuth.js?&lt;/strong&gt; NextAuth.js is an open-source authentication solution created by the community that loves Next.js. It’s built with Next.js in mind the whole way for static, server side, and API route authentication. Check out the &lt;a href="https://next-auth.js.org/getting-started/introduction"&gt;NextAuth.js introduction&lt;/a&gt; to learn more.  &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create an OIDC Application in Okta
&lt;/h2&gt;

&lt;p&gt;You need an OIDC application in Okta which you will authenticate against. I did this process using the Okta CLI but it can also be done by logging into &lt;a href="http://Okta.com"&gt;Okta.com&lt;/a&gt; and creating an app there. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://cli.okta.com/"&gt;Install the Okta CLI&lt;/a&gt;

&lt;ol&gt;
&lt;li&gt;Easily done with Chocolatey &lt;code&gt;choco install okta&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;If you DO NOT have an account run &lt;code&gt;okta register&lt;/code&gt;. If you DO have an account &lt;code&gt;okta login&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create your app with &lt;code&gt;okta apps create&lt;/code&gt; 

&lt;ol&gt;
&lt;li&gt;Take the default app name or rename if you would like&lt;/li&gt;
&lt;li&gt;Choose the &lt;strong&gt;Web&lt;/strong&gt; option for the Type of Application&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Other&lt;/strong&gt; for the Framework of Application&lt;/li&gt;
&lt;li&gt;Redirect URI: &lt;code&gt;http://localhost:3000/api/auth/callback/okta&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Logout Redirect URI: &lt;code&gt;http://localhost:3000&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;You just created your Okta app in the CLI! You will see that a &lt;code&gt;.okta.env&lt;/code&gt; file was created in your Next.js application. This holds the important environment files that you’ll need. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;❗ Add &lt;code&gt;.okta.env&lt;/code&gt; to your .gitignore file. The  &lt;code&gt;.okta.env&lt;/code&gt; file contains sensitive information that should not be in source control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .okta.env created by CLI&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;OKTA_OAUTH2_ISSUER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;URL of your Okta Account&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;OKTA_OAUTH2_CLIENT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Client ID - Preferred not to be shared&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;OKTA_OAUTH2_CLIENT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Client Secret - Definitely do not share&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Initial NextAuth.js setup &amp;amp; configuration
&lt;/h2&gt;

&lt;p&gt;Now it’s time to get into using the next-auth package you installed and set up Okta as an authentication provider. With NextAuth.js it’s a similar workflow for &lt;a href="https://next-auth.js.org/providers/"&gt;adding additional providers&lt;/a&gt;, but I’ll be sticking with Okta for this example. &lt;/p&gt;

&lt;p&gt;1 Create a &lt;code&gt;.env.local&lt;/code&gt; file at the root of your project. This is what the Next.js application will access to get any environment variables. Copy everything over from the &lt;code&gt;.okta.env&lt;/code&gt; into your new &lt;code&gt;.env.local&lt;/code&gt; but remove the &lt;code&gt;export&lt;/code&gt; from in front of the variables.&lt;/p&gt;

&lt;p&gt;❗ Make sure your &lt;code&gt;.env.local&lt;/code&gt; does not go into source control now that you have put sensative information into it. If you created your app with &lt;code&gt;npx create next app --ts&lt;/code&gt; it should already be in your .gitignore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .env.local&lt;/span&gt;
&lt;span class="nx"&gt;OKTA_OAUTH2_CLIENT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;asdfasdf&lt;/span&gt;
&lt;span class="nx"&gt;OKTA_OAUTH2_CLIENT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;asdfasdfasdfasdf&lt;/span&gt;
&lt;span class="nx"&gt;OKTA_OAUTH2_ISSUER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//dev-27410971.okta.com/oauth2/default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 Two more variables need to be added to &lt;code&gt;.env.local&lt;/code&gt;: &lt;code&gt;NEXTAUTH_URL&lt;/code&gt; and &lt;code&gt;SECRET&lt;/code&gt;.&lt;br&gt;
    1. &lt;code&gt;NEXTAUTH_URL&lt;/code&gt; will be &lt;code&gt;http://localhost:3000&lt;/code&gt; for development&lt;br&gt;
    2.  &lt;code&gt;SECRET&lt;/code&gt; is generated by you. I used &lt;a href="https://acte.ltd/utils/randomkeygen"&gt;https://acte.ltd/utils/randomkeygen&lt;/a&gt; and copied the Encryption Key 256 to use for my value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .env.local&lt;/span&gt;
&lt;span class="nx"&gt;OKTA_OAUTH2_CLIENT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;asdfasdf&lt;/span&gt;
&lt;span class="nx"&gt;OKTA_OAUTH2_CLIENT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;asdfasdfasdfasdf&lt;/span&gt;
&lt;span class="nx"&gt;OKTA_OAUTH2_ISSUER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//dev-27410971.okta.com/oauth2/default&lt;/span&gt;
&lt;span class="nx"&gt;NEXTAUTH_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:3000&lt;/span&gt;
&lt;span class="nx"&gt;SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;123456&lt;/span&gt;&lt;span class="nx"&gt;asdf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 Now create a &lt;code&gt;[...nextauth].ts&lt;/code&gt; file under the &lt;code&gt;pages/api&lt;/code&gt; folder of your application. This is a special file used by NextAuth.js, that handles the sign-in and sign-out process for your Next.js application. Paste the following code into your file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//pages/api/[...nextauth].ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NextAuth&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;next-auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Okta&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;next-auth/providers/okta&lt;/span&gt;&lt;span class="dl"&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;authOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Configure one or more authentication providers&lt;/span&gt;
    &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nx"&gt;Okta&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;clientId&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;OKTA_OAUTH2_CLIENT_ID&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;clientSecret&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;OKTA_OAUTH2_CLIENT_SECRET&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;issuer&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;OKTA_OAUTH2_ISSUER&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&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="na"&gt;secret&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;SECRET&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&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;NextAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 Now we move to the &lt;code&gt;pages/_app.tsx&lt;/code&gt; file. We need to add a Provider that wraps our entire application here so that the NextAuth.js session data can be shared between components and pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../styles/globals.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppProps&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;next/app&lt;/span&gt;&lt;span class="dl"&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;SessionProvider&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-auth/react&lt;/span&gt;&lt;span class="dl"&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;Session&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;next-auth&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AppProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;session&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="o"&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;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SessionProvider&lt;/span&gt; &lt;span class="na"&gt;session&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SessionProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&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;At this point, you have authentication setup. What is covered next is the way to use the next-auth package you installed and set up. This will work if you have set up Okta as I showed above or if you have properly set up one or more of the many other &lt;a href="https://next-auth.js.org/providers/"&gt;providers you can use with NextAuth.js&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Adding Authentication to Pages
&lt;/h2&gt;

&lt;p&gt;Now it’s time to look at actually putting content behind authentication in your Next.js pages and API endpoints. Keep in mind this article makes no attempt at having a pretty user interface (UI). The focus is on authentication and I did not want to have any added complexity.  &lt;/p&gt;

&lt;p&gt;In this section, you will see three authentication implementation patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client Side Authentication&lt;/li&gt;
&lt;li&gt;Server Side Authentication&lt;/li&gt;
&lt;li&gt;Next.js API Route Authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Client Side Authentication
&lt;/h3&gt;

&lt;p&gt;Authentication on the client side is not usually the best approach. The reason for this is that the data is sent to the client then authentication happens after. The visitor will not technically see any data on the page that they are not allowed to see but has the ability to access it if they really wanted to. Maybe you don’t have super sensitive that allows for client-side authentication. &lt;/p&gt;

&lt;p&gt;Below is a code sample for executing client-side authentication for a Next.js page. It has a loading state that displays while the authentication status is being checked and then displayed the proper text and signIn or signOut button respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// client-auth.tsx&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;signIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useSession&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-auth/react&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;ClientSideAuth&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&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="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSession&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;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
                Loading...
            &lt;span class="p"&gt;&amp;lt;/&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;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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
                You have logged in &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="nx"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Sign out&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&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;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            Not Logged In &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Sign in&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;Notice the awesome &lt;code&gt;signIn&lt;/code&gt; and &lt;code&gt;signOut&lt;/code&gt; methods passed into the &lt;code&gt;onClick&lt;/code&gt; handlers. These are provided by the &lt;code&gt;next-auth/react&lt;/code&gt; package. These buttons will send users to the &lt;code&gt;api/auth/[...nextauth].ts&lt;/code&gt; route you created and automatically handle the sign in and sign out process for you. It’s that easy to get login work in your application. &lt;/p&gt;

&lt;p&gt;💡&lt;strong&gt;Only using one login provider?&lt;/strong&gt; Consider modifying the code to use &lt;code&gt;signIn('okta')&lt;/code&gt; and it will bring users directly to Okta’s login portal. This works for other providers as well, example &lt;code&gt;signIn('github')&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Server Side Authentication
&lt;/h3&gt;

&lt;p&gt;Performing authentication server side is preferred. This is because the route will be pre-rendered by the server and only the appropriate content will make it to the client. If authenticated only that portion of the content is sent to the client and the same goes for unauthenticated content. &lt;/p&gt;

&lt;p&gt;The below code is a Next.js page with &lt;code&gt;getServerSideProps&lt;/code&gt; indicating the page is using server side rendering (SSR). It may look scary to use &lt;code&gt;unstable_getServerSession&lt;/code&gt; call but that is the recommended method as of now. It is more performant than previous implementations provided NextAuth.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server Side Redirect If Not Authorized&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server-auth.tsx&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;unstable_getServerSession&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-auth/next&lt;/span&gt;&lt;span class="dl"&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;authOptions&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;./api/auth/[...nextauth]&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;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;unstable_getServerSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&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="nx"&gt;authOptions&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&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="na"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;destination&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="na"&gt;permanent&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="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="nx"&gt;ServerSideAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Protected Page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You can view this page because you are signed in as &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&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;The above code checks the session within &lt;code&gt;getServerSideProps&lt;/code&gt; to see if the user is authenticated. If they are we return the user's name and if they are not they get redirected to the homepage. For this app I do not have a dedicated login page, but if your application has a login page that would be a great place to send people that are not authorized. &lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;What does the &lt;code&gt;permanent&lt;/code&gt; value mean in the redirect?&lt;/strong&gt; Permanent can be one of two values true or false. If true the redirect will use the 308 status code which instructs clients/search engines to cache the redirect forever, if false will use the 307 status code which is temporary and is not cached.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next.js API Route Authentication
&lt;/h3&gt;

&lt;p&gt;If you need to add authentication to a Next.js API route you can use the same &lt;code&gt;unstable_getServerSession&lt;/code&gt; that was used above in server side authentication.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// api/api-auth.ts&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;NextApiRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextApiResponse&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&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;unstable_getServerSession&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-auth/next&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;authOptions&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;./auth/[...nextauth]&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextApiRequest&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="nx"&gt;NextApiResponse&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;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;unstable_getServerSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="nx"&gt;authOptions&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is protected content. You can access this content because you are signed in.&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;else&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="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&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;You must be signed in to view the protected content on this page.&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If authorized you send them the protected content, otherwise the code sends back and error to the user making the request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;With NextAuth.js authentication in Next.js become much simpler. With a little setup, you can easily add Okta support to your application, and after that initial setup, it’s very easy to add additional providers like GitHub, Google, or even bring in your own database. &lt;/p&gt;

&lt;p&gt;You now have all the knowledge you need now to create a Next.js application that has content protected by an authentication layer connected to Okta. Remember server side authentication is the safer method for ensuring visitors only see the content they are supposed to. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://next-auth.js.org/"&gt;Next-auth&lt;/a&gt; is a powerful library and I encourage you to explore its more advanced capabilities of it so you can be as informed as possible when it comes to authentication and the security of your application. &lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/thomas-desmond/nextjs-nextauth-okta"&gt;GitHub Repository&lt;/a&gt; with all the code from this article. &lt;/p&gt;

&lt;p&gt;🚨&lt;strong&gt;Need help?&lt;/strong&gt; Reach out to me on my &lt;a href="https://thetombomb.com/posts/bio"&gt;Bio page&lt;/a&gt; or send me a message on &lt;a href="https://twitter.com/ThomasJDesmond"&gt;Twitter&lt;/a&gt;. I’d love to see what you are building and help where I can.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>security</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Introduction to Frontend Development with XM Cloud Hybrid Headless CMS</title>
      <dc:creator>Thomas Desmond</dc:creator>
      <pubDate>Mon, 19 Sep 2022 23:38:51 +0000</pubDate>
      <link>https://forem.com/sitecore/introduction-to-frontend-development-with-xm-cloud-hybrid-headless-cms-3oc</link>
      <guid>https://forem.com/sitecore/introduction-to-frontend-development-with-xm-cloud-hybrid-headless-cms-3oc</guid>
      <description>&lt;p&gt;Thinking about building a frontend with Sitecore Experience Manager Cloud (XM Cloud), Sitecore’s latest headless CMS offering? Read on to learn about the frontend developer experience for XM Cloud. Learn how Sitecore takes a Hybrid Headless approach to CMS’s to differentiate itself from competitors, giving content authors the functionality they need and you the developer, the tools to support frontend development.&lt;/p&gt;

&lt;p&gt;This article explains what XM Cloud is and provides two common workflows for frontend developers, one simple and one more advanced. You’ll also learn about  Sitecore Headless Services, a framework for seamless frontend development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who is this for:
&lt;/h3&gt;

&lt;p&gt;I wrote this article for developers who are currently or plan to develop a frontend against the headless CMS XM Cloud. This article will stay high-level sharing insights into the frontend developer experience and the role Sitecore Headless Services plays in the development process. You’ll find references to a lot of additional resources for topics you may want to take a deep dive into. If you are experienced in Sitecore XM or Headless Services this article may not be for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Sitecore Experience Manager Cloud?
&lt;/h2&gt;

&lt;p&gt;First off, Sitecore Experience Manager Cloud will be referred to as simply XM Cloud going forward. Good, because that’s a lot shorter and easier to read. &lt;/p&gt;

&lt;p&gt;So what is XM Cloud? &lt;strong&gt;XM Cloud is Sitecore’s headless content management system (CMS). XM Cloud bundles Experience Manager, the Pages editor, Sitecore Experience Accelerator (SXA), Headless Services, and Experience Edge.&lt;/strong&gt; It’s capable of creating omnichannel experiences, but the prominent focus is on web apps. &lt;/p&gt;

&lt;p&gt;I just listed a lot of different products and services that make up XM Cloud; it can be overwhelming to attempt to learn them all at once. While Pages and SXA are important to the XM Cloud product &lt;strong&gt;this article is going to focus on Experience Manager, Headless Services, and other important aspects of the frontend developer experience.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The Sitecore Developer Portal has a great &lt;a href="https://developers.sitecore.com/learn/getting-started/xm-cloud-introduction"&gt;XM Cloud Introduction&lt;/a&gt; resource if you want more developer-focused content about XM Cloud. Up next you will learn about the developer experience when working with XM Cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UeEl68By--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efkp63dx7nce403zp2qh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UeEl68By--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efkp63dx7nce403zp2qh.png" alt="Circular diagram depicting benefits of Sitecore XM Cloud" width="880" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Experience
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Development Mindset Shift for Content Management Systems
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Keeping the content author in mind&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have never built a frontend where all the content was hosted in a CMS, then you will need to be prepared for a mindset shift when it comes to your development process.&lt;/p&gt;

&lt;p&gt;Working with XM Cloud or any CMS requires a mindset shift where you need to continuously think about the content author that will be managing the content. You as the developer want to make the content author's life as easy as possible, this may development is a little harder for you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❔ What’s a content author?&lt;/strong&gt;&lt;br&gt;
Sitecore users who manage content are called Content Authors. Sitecore provides content authors the ability to create pages, add components to pages, edit content displayed by the components, and define personalization rules.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With XM Cloud the content author’s will have access to a page designing tool, appropriately named Pages. This allows the content authors to maintain and update content through a simple WYSISYG editor. It will be up to you as the frontend developer to build reusable components that content authors can then utilize inside Pages.&lt;/p&gt;

&lt;p&gt;This also means that no content should be hardcoded into your frontend code. Content authors will want to update text, images, icons, and more all within XM Cloud and your frontend will need to be able to handle these changes.  Don’t worry, Sitecore’s Headless Services helps make this easier and we’ll cover that more later. &lt;/p&gt;

&lt;p&gt;Your frontend will need to be flexible to handle whatever content and layout the content authors throw at you. But this is easy if you follow a component-driven design way of building your application. &lt;/p&gt;

&lt;p&gt;Now let’s take a look at two workflows that frontend developers will run into when working with XM Cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple Workflow: Building Your Frontend Against a Deployed XM Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This first workflow is for developers that want to work strictly on the frontend of their app.&lt;/strong&gt; For this, you will develop against a deployed instance of XM Cloud. Your XM Cloud instance publishes all content out to Experience Edge and you develop against that. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The only two pre-requisites for this are having &lt;a href="https://nodejs.org/en/download/"&gt;Node.js&lt;/a&gt; and the &lt;a href="https://dotnet.microsoft.com/en-us/download"&gt;.NET 6.0 SDK&lt;/a&gt; installed, both of these are available for Windows, Mac, and Linux!&lt;/strong&gt; You need the .NET SDK to use the Sitecore CLI and Node to act as your rendering host to render your frontend locally. With minimal setup, you can be working on your local machine, with any operating system, building and maintaining your frontend. &lt;/p&gt;

&lt;p&gt;💡 This workflow assumes that the deployed XM Cloud instance is all set up and contains the data you need to make your beautiful frontend. You will probably want to get access to the XM Cloud environment still so you can take a peek at what data you are expected to have available to you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jtH6r9uB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0yimva89e9cxuloq7e9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jtH6r9uB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0yimva89e9cxuloq7e9f.png" alt="Diagram depicting frontend being developed against deployed XM Cloud. Data is pulled via Sitecore Experience Edge" width="862" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Model: Workflow with Containers Locally
&lt;/h3&gt;

&lt;p&gt;A common scenario when working with XM Cloud is that you will actually be developing against XM Cloud locally on your machine. You will use the Sitecore CLI and Docker to replicate the XM Cloud environment locally. &lt;/p&gt;

&lt;p&gt;💡 This does mean you will need a Windows machine, unlike the workflow above that could work on any OS.&lt;/p&gt;

&lt;p&gt;In this local containerized scenario, you can build out your frontend against the locally running XM Cloud. Also if you take this approach I would expect you to be or become familiar with some of the features of XM, branching out from your frontend technology. &lt;/p&gt;

&lt;p&gt;I’d recommend becoming familiar with the &lt;a href="https://doc.sitecore.com/xp/en/users/90/sitecore-experience-platform/the-content-editor.html"&gt;Content Editor&lt;/a&gt; and &lt;a href="https://doc.sitecore.com/ea-xmc/en/users/xm-cloud/the-experience-editor.html"&gt;Experience Editor&lt;/a&gt;. As a frontend developer, you do not need to know intricate details of how XM works, but a familiarity to navigate the Content Editor and Experience Editor is helpful. This will make your life easier when you need to look for what data you should be expecting on the frontend. &lt;/p&gt;

&lt;p&gt;Once you are happy with the changes you made in your local containerized environment, you can push those to GitHub, this is the preferred source control currently because of its direct integration with the XM Cloud Deploy App. At this point, the deploy app takes over and handles the deployment of the code to your XM environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oA0DL16L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gztqa6c1kgleorg11aw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oA0DL16L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gztqa6c1kgleorg11aw.png" alt="Diagram depicting a docker container environment locally" width="391" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple vs Advanced Workflow Which to Choose?
&lt;/h3&gt;

&lt;p&gt;Why would you need to use the advanced model?  The advanced workflow allows you to make changes within XM Cloud, essentially create/modify/update &lt;a href="https://developers.sitecore.com/learn/getting-started/sitecore-xm-item-types"&gt;Sitecore items&lt;/a&gt;. With the simple workflow you can only work against what has already been published to Edge from a deployed XM Cloud instance. &lt;/p&gt;

&lt;p&gt;If all you need to do is build your frontend the simple workflow is perfect for you. If you need to make changes within XM Cloud the advanced workflow will probably be the way to go. &lt;/p&gt;

&lt;h2&gt;
  
  
  Building your Frontend against XM Cloud
&lt;/h2&gt;

&lt;p&gt;Now that you know more about the developer experience of building with XM Cloud what will you be building your frontend with? What’s the recommended frontend framework? If XM Cloud is headless can’t you build with any frontend? Let’s jump into answering these questions now. &lt;/p&gt;

&lt;p&gt;A little background first. A typical Headless CMS separates content management from content delivery. The frontend retrieves data from the CMS via APIs. This data is then displayed via a layout created by the frontend developer (that’s you!).&lt;/p&gt;

&lt;p&gt;XM Cloud takes a &lt;em&gt;&lt;a href="https://developers.sitecore.com/content-management/headless#heading-sitecore-s--hybrid-headless-"&gt;Hybrid Headless&lt;/a&gt;&lt;/em&gt; approach because not only does the CMS contain content, but it also contains information on where the content should be in the layout. &lt;strong&gt;With XM Cloud content authors have the power to create content AND move content around in the layout.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This is possible because you will build modular components that do not care where they are on the page. All components are self-contained and independent of one another. This is how you would want your frontend architecture anyway even if you were not using a hybrid headless CMS. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mRlgboTw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q898r9pwkemq34mhb5wv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mRlgboTw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q898r9pwkemq34mhb5wv.png" alt="Diagram depicting a frontend developed with component driven design architecture" width="231" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The hybrid headless approach to CMS’s is one of the biggest differentiators between XM Cloud and other Headless CMS. XM Cloud gives content authors the power to move content pieces anywhere they want on the page and it’s up to you the developer to be able to handle this. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sitecore Headless Services
&lt;/h2&gt;

&lt;p&gt;That’s where &lt;a href="https://developers.sitecore.com/content-management/headless"&gt;Sitecore Headless Services&lt;/a&gt; comes in!&lt;/p&gt;

&lt;p&gt;Headless Services help you develop your frontend against XM Cloud as a backend. Essentially making it easier to handle Sitecore’s approach of allowing content authors to have control of where content is displayed.&lt;/p&gt;

&lt;p&gt;Sitecore Headless Services has been built to support the most popular JavaScript frontend frameworks as well as .Net. However, &lt;strong&gt;for XM Cloud the recommended frontend framework is Next.js because of its ability to do static site generation (SSG) and server-side rendering (SSR) easily on a page-by-page basis.&lt;/strong&gt; Yes, you can choose whatever frontend framework you like but for the best support and easiest integrations, Next.js is recommended.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--794eONSQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgrpgghvdjisyqn0d5kl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--794eONSQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgrpgghvdjisyqn0d5kl.png" alt="Sitecore Headless Services Diagram" width="759" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image depicts how Sitecore Headless Services sits between XM Cloud and your frontend application. You then use the JSS SDK, specifically the Next.js one, to support your frontend development. The combination of Headless Services with the frontend SDK helps you develop more effectively against XM Cloud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❔ Is Sitecore Headless Services Required?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Technically no, but highly recommended. With the release of Experience Edge for XM, you can now query your XM Cloud content via GraphQL from any frontend, web, mobile, watch, tv, or toaster.&lt;/p&gt;

&lt;p&gt;Headless Services has come a long way to help you develop effectively and efficiently again XM Cloud. It is my recommendation that you make a strong effort to use Headless Services with Next.js in your XM Cloud implementation. &lt;/p&gt;

&lt;p&gt;There is quite a bit more detail to Headless Services that I do not want to get into with this article. I hope to make or share more hands-on in-depth tutorials to help you become a proficient frontend developer jumping into the Sitecore XM Cloud world. &lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://developers.sitecore.com/content-management/headless"&gt;Headless Services&lt;/a&gt; page on the developer portal to learn more. &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;XM Cloud is an exciting release for Sitecore. It brings the popular hybrid headless Experience Manger to the cloud. Lots of work has been put in to make the local containerized workflow as seamless as possible, and once you have XM Cloud deployed you can take advantage of building directly against XM cloud with no containers. Headless Services is continuously improving to meet the needs of frontend developers building against XM Cloud.&lt;/p&gt;

&lt;p&gt;There is still plenty to learn to get the most out of XM Cloud but I hope this introduction was helpful.  &lt;/p&gt;

&lt;p&gt;If you have made it this far congratulations! If this content was helpful to you please share it with your peers. If not please reach out to me on Twitter &lt;a href="https://twitter.com/ThomasJDesmond"&gt;@ThomasJDesmond&lt;/a&gt;, Sitecore Slack, or the contact form on my &lt;a href="https://thetombomb.com/posts/bio"&gt;Bio page&lt;/a&gt; and let me know what this article needs to be more valuable. I appreciate the feedback!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Further XM Cloud Learning Content
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;XM Cloud Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.sitecore.com/learn/getting-started/xm-cloud-introduction"&gt;XM Cloud Introduction - Sitecore Developer Portal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Sitecore/XM-Cloud-Introduction"&gt;XM Cloud Code Sample - Powers Sitecore MVP site and all SUGCON event sites&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Headless Services Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.sitecore.com/content-management/headless"&gt;Headless Service - Sitecore Developer Portal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://doc.sitecore.com/ea-xmc/en/developers/xm-cloud/sitecore-headless-development.html"&gt;Sitecore Headless Development - Sitecore Documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=ugPy7BjH0H0&amp;amp;list=PL1jJVFm_lGnwZup4L4BjITS2sKr4rpMfI"&gt;Headless and JSS - YouTube Playlist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👋 Have a specific question about XM Cloud or other Sitecore products? Consider joining the &lt;a href="https://siteco.re/sitecoreslack"&gt;Sitecore Slack Channel&lt;/a&gt; or asking questions on &lt;a href="https://sitecore.stackexchange.com/"&gt;Sitecore Stack Exchange&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>cms</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>sitecore</category>
    </item>
  </channel>
</rss>
