<?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: Guy Dumais</title>
    <description>The latest articles on Forem by Guy Dumais (@guydumais).</description>
    <link>https://forem.com/guydumais</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%2F569435%2F345ef913-5ff3-43f2-905c-bfcba4a38024.jpeg</url>
      <title>Forem: Guy Dumais</title>
      <link>https://forem.com/guydumais</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/guydumais"/>
    <language>en</language>
    <item>
      <title>How to deploy a strict Content Security Policy (CSP) with Next.js</title>
      <dc:creator>Guy Dumais</dc:creator>
      <pubDate>Sat, 11 Sep 2021 13:05:07 +0000</pubDate>
      <link>https://forem.com/guydumais/how-to-deploy-a-strict-content-security-policy-csp-with-next-js-nfj</link>
      <guid>https://forem.com/guydumais/how-to-deploy-a-strict-content-security-policy-csp-with-next-js-nfj</guid>
      <description>&lt;p&gt;Based on the most comprehensive study to date from Google, 95% of real-world Content Security Policy (CSP) deployments are bypassed and 99.34% of hosts with CSP use policies that offer no benefit against XSS.&lt;/p&gt;

&lt;p&gt;This is why Google suggests that the model of designating trust by specifying URL whitelists from which scripts can execute should be replaced with an approach based on nonces and hashes, already defined by the CSP specification and available in major browser implementations. Hence the name strict CSP.&lt;/p&gt;

&lt;p&gt;In the context of a Single Page App (SPA) such as the Next.js React framework, we need to use a Hashed-based CSP in order to properly integrate a strict CSP which will offer real protection against CSS attacks.&lt;/p&gt;

&lt;p&gt;Depending on the complexity of your application, the integration of a hash-based Content Security Policy could be trivial and require a lot of code manipulation. That’s why I’ve come to build a package on NPM specifically designed for Next.js to allow developers to integrate strict CSP in a snap with just a few lines of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  next-strict-csp
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/next-strict-csp"&gt;next-strict-csp&lt;/a&gt; is a hash-based Strict Content Security Policy generator for Next.js that is easily integrated in the _document.tsx file of your Next.js application. Once in production, it will automatically inject the hashes into the content security policy meta tag and protect against XSS once deployed and cached on CDN.&lt;/p&gt;

&lt;p&gt;Here is an example of &lt;strong&gt;_document.tsx&lt;/strong&gt; with basic integration of next-strict-csp:&lt;br&gt;
&lt;/p&gt;

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

// Next.js libraries
import Document, { Html, Head, Main, NextScript } from 'next/document'

// Next Strict Content Security Policy
import { NextStrictCSP } from 'next-strict-csp'

...

// Enable Head Strict CSP in production mode only
const HeadCSP = process.env.NODE_ENV === 'production' ? NextStrictCSP : Head

...

// Document component
class MyDoc extends Document {

  render() {
    return (
      &amp;lt;Html&amp;gt;
        &amp;lt;HeadCSP&amp;gt;
          { process.env.NODE_ENV === 'production' &amp;amp;&amp;amp; 
          &amp;lt;meta httpEquiv="Content-Security-Policy" /&amp;gt;
          }

          ...

        &amp;lt;/HeadCSP&amp;gt;
        &amp;lt;body&amp;gt;

          ...

          &amp;lt;Main /&amp;gt;
          &amp;lt;NextScript /&amp;gt;

          ...

        &amp;lt;/body&amp;gt;
      &amp;lt;/Html&amp;gt;
    )
  }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once put live in production, you'll get a content security policy meta tag that looks like this:&lt;br&gt;
&lt;code&gt;&amp;lt;meta http-equiv="Content-Security-Policy" content="script-src 'strict-dynamic' 'sha256-XOzjewwkvGMLaoj+oYCiOZ3kRwb6RT1Ph6vn4qL+XI0=' 'unsafe-inline' http: https:;" slug="/"&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With a strict CSP, you need to hash your inline scripts as well. This could be easily achieved with next-strict-csp by integrating your inline scripts in an array like this in &lt;strong&gt;_document.tsx&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

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

// Next.js libraries
import Document, { Html, Head, Main, NextScript } from 'next/document'

// Next Strict Content Security Policy
import { NextStrictCSP } from 'next-strict-csp'

...

// Cloudflare Insights Script (Optional)
const cloudflareJs = `var s = document.createElement('script')
s.src = 'https://static.cloudflareinsights.com/beacon.min.js'
s.setAttribute('data-cf-beacon', '{"token": "YOUR CLOUDFLARE WEB ANALYTICS TOKEN STRING"}')
document.body.appendChild(s)`

// Google Tag Manager Script (Optional)
const GTMJs = `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&amp;amp;l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','YOUR GOOGLE TAG MANAGER ID STRING');`

// Next Strict CSP
// Inline scripts to hash  (Optional)
NextStrictCSP.inlineJs = [
  cloudflareJs,
  GTMJs
]

...

// Enable Head Strict CSP in production mode only
const HeadCSP = process.env.NODE_ENV === 'production' ? NextStrictCSP : Head

...

// Document component
class MyDoc extends Document {

  render() {
    return (
      &amp;lt;Html&amp;gt;
        &amp;lt;HeadCSP&amp;gt;
          { process.env.NODE_ENV === 'production' &amp;amp;&amp;amp; 
          &amp;lt;meta httpEquiv="Content-Security-Policy" /&amp;gt;
          }

          ...

          {/* Google Tag Manager */}
          { process.env.NODE_ENV === 'production' &amp;amp;&amp;amp; 
          &amp;lt;script 
            dangerouslySetInnerHTML={{
                __html: GTMJs
            }}
          /&amp;gt;
          }
          {/* End Google Tag Manager */}

        &amp;lt;/HeadCSP&amp;gt;
        &amp;lt;body&amp;gt;
          { process.env.NODE_ENV === 'production' &amp;amp;&amp;amp; 
          &amp;lt;noscript
            dangerouslySetInnerHTML={{
                __html: `&amp;lt;iframe src="https://www.googletagmanager.com/ns.html?id=YOUR GOOGLE TAG MANAGER ID STRING" height="0" width="0" style="display:none;visibility:hidden"&amp;gt;&amp;lt;/iframe&amp;gt;`,
            }}
          /&amp;gt;
          }

          ...

          &amp;lt;Main /&amp;gt;
          &amp;lt;NextScript /&amp;gt;
          {/* Cloudflare Web Analytics */}
          {/*&amp;lt;script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon={`{"token": "YOUR CLOUDFLARE WEB ANALYTICS TOKEN STRING"}`}&amp;gt;&amp;lt;/script&amp;gt;*/}
          {process.env.NODE_ENV === 'production' &amp;amp;&amp;amp; 
          &amp;lt;script dangerouslySetInnerHTML={{
            __html: cloudflareJs
          }} /&amp;gt;
          }
          {/* End Cloudflare Web Analytics */}

          ...

        &amp;lt;/body&amp;gt;
      &amp;lt;/Html&amp;gt;
    )
  }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once live, your inline scripts hashes will be injected into the content security policy meta tag like this:&lt;br&gt;
&lt;code&gt;&amp;lt;meta http-equiv="Content-Security-Policy" content="script-src 'strict-dynamic' 'sha256-XOzjewwkvGMLaoj+oYCiOZ3kRwb6RT1Ph6vn4qL+XI0=' 'sha256-QSxH3dqIUPdeBvyxSZSuIbZfgtCo/yuqnzU+5gtq9Ak=' 'sha256-7V8IQTE3j8PL2rD62J9XsmUhchGnkkyNIQfwoYVK04I=' 'unsafe-inline' http: https:;" slug="/"&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Last word
&lt;/h2&gt;

&lt;p&gt;Hope you enjoyed next-strict-csp and don't hesitate to leave a comment to let me know what you think about it.&lt;/p&gt;

&lt;p&gt;Thanks for reading, see you!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>security</category>
    </item>
    <item>
      <title>Next.js: The Ultimate Cheat Sheet To Page Rendering</title>
      <dc:creator>Guy Dumais</dc:creator>
      <pubDate>Mon, 19 Jul 2021 21:51:19 +0000</pubDate>
      <link>https://forem.com/guydumais/next-js-the-ultimate-cheat-sheet-to-page-rendering-55eb</link>
      <guid>https://forem.com/guydumais/next-js-the-ultimate-cheat-sheet-to-page-rendering-55eb</guid>
      <description>&lt;p&gt;Next.js uses 4 rendering strategies to build, deliver and render a React Single Page App (SPA):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Static-Site Generation (SSG)&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;2. Server-Side Rendering (SSR)&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;3. Incremental Static Regeneration (ISR)&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;4. Client-Side Rendering (CSR)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the easiest and most complete cheat sheet to quickly understand how Next.js page rendering strategies works. Moreover, this unique cheat sheet clearly reveals how each strategy influences the Core Web Vitals signals: TTFB, FP, FCP, LCP, TBT and TTI.&lt;/p&gt;

&lt;p&gt;Detailed explanations are also included to help you choose the right page rendering strategy for all use cases and thus create speedy Web applications that Google and visitors love.&lt;/p&gt;

&lt;p&gt;P.S.: Thanks in advance for including this cheat sheet in your blog articles and mentioning the author with a link back to this cheat sheet like this: &lt;a href="https://guydumais.digital/blog/next-js-the-ultimate-cheat-sheet-to-page-rendering/" rel="noopener noreferrer"&gt;Next.js: The Ultimate Cheat Sheet To Page Rendering&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vcs6ar5teakp6b8g6si.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vcs6ar5teakp6b8g6si.jpg" alt="Next.js: The Ultimate Cheat Sheet To Page Rendering - Infographic"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;p&gt;The 4 page rendering strategies are identified with their respective acronym (SSG, SSR, ISR and CSR) and laid out in columns besides each other in the middle of the infographic.&lt;/p&gt;

&lt;p&gt;Completely on the left side of these 4 columns you’ll find the 6 steps involved during the processing flow from the build step on the server side up to the client-side rendering.&lt;/p&gt;

&lt;p&gt;Completely on the right side of these 4 columns you’ll find where each step happens in the processing flow which is either server side or client side.&lt;/p&gt;

&lt;p&gt;For each strategy column you’ll see where and when a build action (page generation) is executed in the step. You’ll also see the generated content flow (HTML - React/CSS/JS/Data) during each single step.&lt;/p&gt;
&lt;h3&gt;
  
  
  Core Web Vitals
&lt;/h3&gt;

&lt;p&gt;The Core Web Vitals (CWV), parts of the &lt;a href="https://guydumais.digital/blog/ready-for-the-google-page-experience-update/" rel="noopener noreferrer"&gt;new page experience ranking factor from Google&lt;/a&gt;, are identified using 3 distinctive background colors, each related to the performance impact on the CWV.&lt;/p&gt;

&lt;p&gt;A red color means POOR performance results, an orange color means GOOD performance while a green color means the BEST performance.&lt;/p&gt;
&lt;h3&gt;
  
  
  Live Demo
&lt;/h3&gt;

&lt;p&gt;You’ll find a live demo with example source code on Github for testing the performance of each page rendering strategies discussed in the cheat sheet:&lt;br&gt;
&lt;a href="https://next-page-rendering.vercel.app/" rel="noopener noreferrer"&gt;https://next-page-rendering.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Static-Site Generation (SSG)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Static-Site Generation (SSG)&lt;/strong&gt; is the default strategy offered by Next.js to generate web pages. Next.js recommends this strategy to get the best performance results as static content is distributed faster using CDNs which are closer to your visitors and thus leading to a faster Time to First Byte (TTFB).&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps description
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt;: Next.js generates a Single Page App in an .html file along with the .css and .js on the server. This step called pre-rendering is done only once at build time when you run the next build command. That is usually done when you deploy your application. This is during this step that all the page coding (HTML) is generated including the React code, CSS, JavaScript and optionally the data if the page is using any data fetching method such as &lt;a href="https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation" rel="noopener noreferrer"&gt;&lt;code&gt;getStaticProps()&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation" rel="noopener noreferrer"&gt;&lt;code&gt;getStaticPaths()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 2&lt;/strong&gt;: The client requests the Single Page App from the CDN.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 3&lt;/strong&gt;: The client downloads the Single Page App from the CDN.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 4&lt;/strong&gt;: The client parses and renders the Single Page App into the browser. This is where the 3 Core Web Vitals signals (First Paint, First Contentful Paint and Largest Contentful Paint) are fired. Because the HTML of the page has been pre-rendered on the server side, the client browser just has to load and render it as is. And because the page is coded in a way that allows the browser to render it with minimum JavaScript code, render-blocking is reduced to its minimum leading to good performance results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 5&lt;/strong&gt;: The React (JavaScript) code is run to (re)Hydrate the page. Even though the page has been pre-built, this extra step is required to allow React to attach or activate the JavaScript events to its Virtual DOM and make the page interactive. Because JavaScript is run at this point, Total Blocking Time is affected by this extra step. Also, because the browser has to wait for the hydration process to complete, Time To Interactive is also affected.&lt;/p&gt;

&lt;p&gt;Here is the complete Typescript code of a web page that uses Next.js' Static-Site Generation strategy (SSG):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Next.js libraries
import Head from 'next/head'

// Custom Components
import BackToHome from 'components/BackToHome'

// Page component
export default function StaticSideGeneration({ jsonData }) {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Static-Site Generation (SSG) • Guy Dumais&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="Example page using Static-Site Generation (SSG) with Next.js 11 and React 17"/&amp;gt;
        &amp;lt;meta name="viewport" content="initial-scale=1.0, width=device-width" /&amp;gt;
      &amp;lt;/Head&amp;gt;
      &amp;lt;BackToHome/&amp;gt;
      &amp;lt;h1&amp;gt;Static-Site Generation (SSG)&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Data fetched at build-time on the server-side before sending to the client.&amp;lt;/p&amp;gt;
      &amp;lt;ul&amp;gt;
      {
        jsonData.data.map((e) =&amp;gt; (
          &amp;lt;li key={e.id}&amp;gt;{e.email}&amp;lt;/li&amp;gt;
        ))
      }
      &amp;lt;/ul&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export async function getStaticProps() {
  const res = await fetch('https://reqres.in/api/users?page=2')
  const jsonData = await res.json()

  return {
    props: {
      jsonData, // will be passed to the page component as props
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Server Side Rendering (SSR)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Server Side Rendering (SSR)&lt;/strong&gt; is the second strategy offered by Next.js to generate web pages. Next.js recommends to avoid using this strategy as much as possible to get the best performance results as the static content is built (pre-rendered) and distributed per-request only. Because of the extra time required by the build process, the Time to First Byte (TTFB) signal is increased and leads to poor results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps description
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt;: Next.js does not generate (pre-render) any page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 2&lt;/strong&gt;: The client requests the Single Page App from the server. Next.js generates (pre-render) a Single Page App in an .html file along with the .css and .js on the server. This is during this step that all the page coding (HTML) is generated including the React code, CSS, JavaScript and optionally the data if the page is using the &lt;a href="https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering" rel="noopener noreferrer"&gt;&lt;code&gt;getServerSideProps()&lt;/code&gt;&lt;/a&gt; data fetching method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 3&lt;/strong&gt;: The client downloads the Single Page App from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 4&lt;/strong&gt;: Same as STEP 4 in SSG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 5&lt;/strong&gt;: Same as STEP 5 in SSG.&lt;/p&gt;

&lt;p&gt;Here is the complete Typescript code of a web page that uses Next.js' Server Side Rendering strategy (SSR):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Next.js libraries
import Head from 'next/head'

// Custom Components
import BackToHome from 'components/BackToHome'

// Page component
export default function ServerSideRendering({ jsonData }) {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Server-Side Rendering (SSR) • Guy Dumais&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="Example page using Server-Side Rendering (SSR) with Next.js 11 and React 17"/&amp;gt;
        &amp;lt;meta name="viewport" content="initial-scale=1.0, width=device-width" /&amp;gt;
      &amp;lt;/Head&amp;gt;
      &amp;lt;BackToHome/&amp;gt;
      &amp;lt;h1&amp;gt;Server-Side Rendering (SSR)&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Data fetched on the server-side at &amp;lt;b&amp;gt;each&amp;lt;/b&amp;gt; request before sending to the client.&amp;lt;/p&amp;gt;
      &amp;lt;ul&amp;gt;
      {
        jsonData.data.map((e) =&amp;gt; (
          &amp;lt;li key={e.id}&amp;gt;{e.email}&amp;lt;/li&amp;gt;
        ))
      }
      &amp;lt;/ul&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

export async function getServerSideProps() {
  const res = await fetch('https://reqres.in/api/users?page=2')
  const jsonData = await res.json()

  return {
    props: {
      jsonData, // will be passed to the page component as props
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Incremental Static Regeneration (ISR)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Incremental Static Regeneration (ISR)&lt;/strong&gt; is the third strategy offered by Next.js to generate web pages. It is the same as Static Site Generation except that content can be rebuilt when the page is updated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps description
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt;: Same as STEP 1 in SSG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 2&lt;/strong&gt;: The client requests the Single Page App from the CDN. Also, if the page is using the data fetching method getStaticProps() combined with the revalidate option, then the page is regenerated if the data returned from the fetching results has been updated. Next.js recommends using this method for a huge site having over 1,000 pages. Because pre-rendering each page takes time, using this incremental method will pre-render on the first request and when the page content is updated only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 3&lt;/strong&gt;: Same as STEP 3 in SSG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 4&lt;/strong&gt;: Same as STEP 4 in SSG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 5&lt;/strong&gt;: Same as STEP 5 in SSG.&lt;/p&gt;

&lt;p&gt;Here is the complete Typescript code of a web page that uses Next.js' Incremental Static Regeneration strategy (ISR):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Next.js libraries
import Head from 'next/head'

// Custom Components
import BackToHome from 'components/BackToHome'

// Page component
export default function IncrementalStaticGeneration({ jsonData }) {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Incremental Static Regeneration (ISR) • Guy Dumais&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="Example page using Incremental Static Regeneration (ISR) with Next.js 11 and React 17"/&amp;gt;
        &amp;lt;meta name="viewport" content="initial-scale=1.0, width=device-width" /&amp;gt;
      &amp;lt;/Head&amp;gt;
      &amp;lt;BackToHome/&amp;gt;
      &amp;lt;h1&amp;gt;Incremental Static Regeneration (ISR)&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Data fetched at build-time on the server-side and rebuilt when data updated.&amp;lt;/p&amp;gt;
      &amp;lt;ul&amp;gt;
      {
        jsonData.data.map((e) =&amp;gt; (
        &amp;lt;li key={e.id}&amp;gt;{e.email}&amp;lt;/li&amp;gt;
      ))
      }
      &amp;lt;/ul&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://reqres.in/api/users?page=2')
  const jsonData = await res.json()

  return {
    props: {
      jsonData, // will be passed to the page component as props
    },

    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every second
    revalidate: 100, // In seconds
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Client Side Rendering (CSR)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Client Side Rendering (CSR)&lt;/strong&gt; is the fourth strategy offered by Next.js to generate web pages. It is the same as Static Site Generation except that parts of the content can be built on the client side.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps description
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt;: Same as STEP 1 in SSG except that the content (data) is not pre-rendered nor included in the static bunch. Which results in a smaller file size thus leading to shorter download time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 2&lt;/strong&gt;: Same as STEP 2 in SSG but without content (data).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 3&lt;/strong&gt;: Same as STEP 3 in SSG but without content (data).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 4&lt;/strong&gt;: Same as STEP 4 in SSG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 5&lt;/strong&gt;: Same as STEP 5 in SSG but without content (data).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 6&lt;/strong&gt;: The client fetches the content (data) and React updates the UI. This method is useful, for example, when you want to show up a skeleton page with static content and then progressively inject the data in a page requiring a long wait time for data fetching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// React
import { useEffect, useState } from 'react'

// Next.js
import Head from 'next/head'
import Link from 'next/link'

// Custom Components
import BackToHome from 'components/BackToHome'

// Page component
export default function ClientSideRendered() {

  const [state, setState] = useState([] as any)

  const getData = async () =&amp;gt; {
    const res = await fetch('https://reqres.in/api/users?page=2')
    const jsonData = await res.json()
    setState(jsonData)
  }

  useEffect(() =&amp;gt; {
    getData()
  }, [])

  return (
    &amp;lt;&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Client-Side Rendering (CSR) • Guy Dumais&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="Example page using Client-Side Rendering (CSR) with Next.js 11 and React 17"/&amp;gt;
        &amp;lt;meta name="viewport" content="initial-scale=1.0, width=device-width" /&amp;gt;
      &amp;lt;/Head&amp;gt;
      &amp;lt;BackToHome/&amp;gt;
      &amp;lt;h1&amp;gt;Client-Side Rendering (CSR)&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Data fetched on the client-side only.&amp;lt;/p&amp;gt;
      &amp;lt;ul&amp;gt;
      {
        state.data?.map((e) =&amp;gt; (
          &amp;lt;li key={e.id}&amp;gt;{e.email}&amp;lt;/li&amp;gt;
        ))
      }
      &amp;lt;/ul&amp;gt;
    &amp;lt;/&amp;gt;
  )

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nextjs</category>
      <category>react</category>
      <category>corewebvitals</category>
      <category>performance</category>
    </item>
    <item>
      <title>Why I choose Next.js and Sanity for my new blog</title>
      <dc:creator>Guy Dumais</dc:creator>
      <pubDate>Sat, 03 Jul 2021 12:50:08 +0000</pubDate>
      <link>https://forem.com/guydumais/why-i-choose-next-js-and-sanity-for-my-new-blog-4mlb</link>
      <guid>https://forem.com/guydumais/why-i-choose-next-js-and-sanity-for-my-new-blog-4mlb</guid>
      <description>&lt;h2&gt;
  
  
  The big move...
&lt;/h2&gt;

&lt;p&gt;One of the main reason I've always love doing this job is the fact that technologies are always evolving for the better. They are constantly improving ways to do more with less. And it still happening nowadays with the latest &lt;a href="https://jamstack.org/"&gt;Jamstack&lt;/a&gt; technologies such as &lt;a href="https://reactjs.org/"&gt;React.js&lt;/a&gt;, &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; and &lt;a href="https://www.sanity.io/"&gt;Sanity&lt;/a&gt; to name a few. I see it as a kind of technology revolution.&lt;/p&gt;

&lt;p&gt;As a Software Engineer, I've got to keep up to date with the latest technologies and because no Software Engineer knows everything, the more you know, the better your web applications will be, and the better the user experience will be as well. And this is the main reason why I've decided to upgrade my knowledge and move my personal blog into the Jamstack world to experience the REAL experience on the ground.&lt;/p&gt;

&lt;p&gt;And this is also the reason I've written this article in hope that it can help anyone's willing to move into the Jamstack world, also looking for choosing the right technologies from the start to build and scale your online business without having to restart  from scratch as technology evolve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overcoming challenges
&lt;/h2&gt;

&lt;p&gt;Despite my huge IT background mixed with my latest web skills it was still difficult to get there. But I finally succeeded and the end results paid back. The proof is that I'm now having this blog which is entirely using the latest Jamstack technologies giving much better SEO results with &lt;a href="https://web.dev/measure/"&gt;Lighthouse&lt;/a&gt; scores over 90% on almost every single pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My first challenge&lt;/strong&gt; has been to learn React developed by Facebook which required a brand new way to think when developing. In the end, you have to think in React. Briefly, React is a Javascript library that help you build dynamic user interfaces.&lt;/p&gt;

&lt;p&gt;The main approach to adopt while developing in React is to split your application elements in components. It was a bit confusing at start, specially for an object oriented programmer like me, but once you catch the idea behind the library, the end result is a much better code which is much easier to maintain while the application is growing. This is a huge productivity boost for a developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My second challenge&lt;/strong&gt; has been to find a framework to build and host my website which is now a progressive web application (PWA). There are many solutions available out there each offering different advantages depending on your needs.&lt;/p&gt;

&lt;p&gt;After giving a try to &lt;a href="https://www.gatsbyjs.com/"&gt;Gatsby&lt;/a&gt;, which is a great framework as well, I've switched to Next.js because it allows me to do more with less in the end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My third challenge&lt;/strong&gt; has been to find a way to host and manage my blog content. Since React is used to only manage the UI (frontend) part of a Web application, you need another technology to host and manage your content (backend). That's what I call the CMS Stack or the Content Stack.&lt;/p&gt;

&lt;p&gt;The CMS Stack could be WordPress, Magento, Joomla or whatever content manager you prefer. The beauty with Jamstack is that you could still use any content management system (CMS) behind the scene and use React as the UI to pull and push this content to your visitors. One of the main advantages of the stack approach is that you could change your CMS without having to rebuild your UI from scratch.&lt;/p&gt;

&lt;p&gt;After lot of searching and experimentations, I've finally opted to use Sanity as my CMS, explained in more details further down in this article, for its brand new powerful and flexible structured content approach using portable text, which, in my humble opinion, is going to get adopted widely in the future.&lt;/p&gt;

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

&lt;p&gt;In short, Next.js is a framework to generate modern websites using React. More over, it allows you to run serverless functions which make it very useful to quickly run some backend business logic such as authentication, payments to name only few.&lt;/p&gt;

&lt;p&gt;I got a crush for the production part when time has come to publish my work online in just a few clicks with their Vercel platform which offer a generous free offer for hosting your web application.&lt;/p&gt;

&lt;p&gt;For sure, I'll be posting more about how to do things the right way with Next.js. Once you understand the way Next.js is doing things behind the scene, you'll do amazing things with few efforts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity
&lt;/h2&gt;

&lt;p&gt;Sanity.io is a content management system (CMS) that is framework independent. What I mean by that is that I can connect other frontends to my blog content (texts, images, etc.) that no more rely on a specific CMS cause it's saved in JSON format which can be consumed by any API compatible UI framework such as Next.js, Gatsby, Vue.js.&lt;/p&gt;

&lt;p&gt;So now, I can switch my frontend framework without having to rebuild my content. Also, I can switch my content to a CDN or any other server that can host and deliver JSON files without having to rebuild my frontend. For exemple, I could move my JSON content on Google Drive.&lt;/p&gt;

&lt;p&gt;Sanity.io lets me work with structured content. That means I can add more content types. Who knows, I might add my portfolio, maybe a podcast, some products that I need to market, or my personal music creations.&lt;/p&gt;

&lt;p&gt;Also, Sanity comes with a Studio Editor which is fully customizable to make it work the way you want for your specific needs. Again, I'll be posting more about how Sanity and the ways to do things correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwind
&lt;/h2&gt;

&lt;p&gt;I've never been a big fan of css frameworks because of the extra weight added to each page load and the learning curve. The first time I looked at Tailwind I liked the approach which consist of adding classes a bit like Bootstrap. But I didn't liked the learning curve and the extra weight of the version 1 framework.&lt;/p&gt;

&lt;p&gt;But I've changed my mind since I looked and tried the version 2, now we're talking about something interesting. Since version 2, only the styles used in the webpage will be loaded. Which means a smaller footprint for the css.&lt;/p&gt;

&lt;h2&gt;
  
  
  The final word
&lt;/h2&gt;

&lt;p&gt;Who could have said a few years ago that Javascript, which was used to do basic calculations and animations in web pages, would become one of the main language used for building web applications. In my humble opinion, with the growing popularity of React, Javascript is going to become the most popular programming language on the web.&lt;/p&gt;

&lt;p&gt;The old static web page composed mainly of html and css, dynamically generated server-side using a monolithic server architecture is dying . Nowadays we're talking about client-side web applications powered worldwide on hundreds of CDN servers. Which make your web applications more reliable, cheaper to host but above all, much more secure.&lt;/p&gt;

&lt;p&gt;In my humble opinion, the best approach to use is to create a minimum viable product (MVP) like this blog, using the LEAN method. That is to say that even if it does not contain all the features that I would like to have at the moment, I have integrated the minimum elements such as Google Analytics, Opengraph, metadata and responsive images, to allow me to create content on a scalable platform adapted to current technological requirements.&lt;/p&gt;

&lt;p&gt;But above all, the main goal is to create the best web experience as possible for the mobile user which now consume our content using any kind of devices from anywhere.&lt;/p&gt;

&lt;p&gt;Over time, I'll be adding new features such as Authentication for accessing exclusive content, newsletter subscription and Internationalization (i18n) which I've learned recently and took me a while to mastered, specially the English/French translations with React routing that is not ready out-of-the-box but mature enough to be put live in production.&lt;/p&gt;

&lt;p&gt;Now that I have explored and found the right frameworks, let's build great content to make this blog my own special place on the internet.&lt;/p&gt;

&lt;p&gt;Keep coming back, my next goal is to integrate a Newsletter...&lt;/p&gt;

&lt;p&gt;See You!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>sanity</category>
      <category>jamstack</category>
      <category>react</category>
    </item>
  </channel>
</rss>
