PageSourceSearch

https://pixelpoint.io/component---src-templates-blog-post-jsx-cont…evelopment-index-md-87499bc7f5ec0c81f670.js

js pixelpoint.io collected 2026-10-03 22:11:50 UTC 38,667 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkpixelpoint_website=self.webpackChunkpixelpoint_website||[]).push([[6699],{3456:function(e,t,a){a.r(t),a.d(t,{Head:function(){return u},default:function(){return h}});var n=a(8453),i=a(6540);function s(e){const t=Object.assign({p:"p",a:"a",ul:"ul",li:"li",span:"span",h2:"h2",h3:"h3",code:"code",ol:"ol"},(0,n.RP)(),e.components),{Video:a}=t;return a||function(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Video",!0),i.createElement(i.Fragment,null,i.createElement(t.p,null,"Gatsby and Next.js, from a first glance, could look pretty much the same. Both are React-based frameworks, do SSR, SSG, have big communities. We actively use both technologies in ",i.createElement(t.a,{href:"https://pixelpoint.io/"},"our agency"),", but we think that they fit better for different use cases. I often get asked why we use Gatsby instead of Next.js for websites development? This article will explain it in detail."),"\n",i.createElement(t.p,null,"Choosing the technology for website development, we need to keep in mind a few factors"),"\n",i.createElement(t.ul,null,"\n",i.createElement(t.li,null,"Speed of development"),"\n",i.createElement(t.li,null,"Editorial experience"),"\n",i.createElement(t.li,null,"Maintainability"),"\n",i.createElement(t.li,null,"Scalability"),"\n",i.createElement(t.li,null,"Customization"),"\n"),"\n",i.createElement(t.p,null,"Here is how a feature comparison table between two frameworks might look like. They are pretty much the same, aren’t they?"),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 127.01149425287358%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAAsTAAALEwEAmpwYAAACO0lEQVR42o1Ua5OaQBC8//+/8sXkLtEPifHwBEEBXxS77GMArfTuyEPJpdJVbi0svT3TM+NL7XG9Xtu2rf+GpmlwipWIsN5uN6x89IKf1jqO4yRJ1AQ4KooiDMPz+Yx9WZbr9fp0Ollr72RjzNbDeOgR8OjIHxuQQXDkIHBkIkcmjzzPIR5FES7Gd0iB/DFWSMxUrGvCQ1M3M5VUjW2oCxtXXi6XqqpsB+qAvbF2JXNlDfn3K5FVFlfRQIYyMmSpB3jyWxkzGcfYi/8ks/JC7HryXCTyicxm8tdT8k+Z9mH/lpOwj8cj3GbPgM1mg1UIgY+0Na/ltnJk59msjIRVdW8Y7jscDoj82AF7vEGd3NVE7/IAKqutqly5/YSMNU3TvENP/q52noBS1ci/IvNQKpblJu1RswXGtouQlHaNgYvK+MEwKMMwlNo+gg0Dqs2etLFefPlkGHcYDAuCgJt07LZTnn+uzB3GGT6Vmks1r4Y6I2c5LdU/mmQpUt3VeSnT57DhM+au92yYZvCJXsVWkeHyfBNbSboZlwpzh0FD8IUHd9toMLJe+V3mzx0G5m632+/3CAH/Cq63eB49+YcYBuOrmgwGNwn42ECWX47ICZPBbhcRSWXrUdhQ5g7LsgyD3TvHdQ6LIewiSY1PalCGZtzhoc7k6ty8ffR1/lJFpVV3w/gjVu7ncWQ2oblNmEGBvN2BzPV4MAC0J2Ie0+5kPxn217bWBnsMBvKXGIxxzjwJ9Anq0VHbtH10fwDKmZatyUgbIQAAAABJRU5ErkJggg==\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/09400/compare1.webp 174w,\n/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/3266f/compare1.webp 348w,\n/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/657d2/compare1.webp 696w,\n/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/8d5bc/compare1.webp 962w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/88093/compare1.png 174w,\n/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/91d18/compare1.png 348w,\n/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/871fd/compare1.png 696w,\n/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/21cd7/compare1.png 962w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/3dda24cc0b0e1d708d99bdfc8c9fc83a/871fd/compare1.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",i.createElement(t.p,null,"However, those minor differences could cause a huge impact on website development."),"\n",i.createElement(t.p,null,"Now, let’s go over what needs to be on a website and check how the frameworks handle the same tasks."),"\n",i.createElement(t.h2,{id:"everything-begins-or-ends-with-favicon"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#everything-begins-or-ends-with-favicon"},i.createElement(t.span,{className:"icon icon-link"})),"Everything begins or ends with Favicon"),"\n",i.createElement(t.p,null,"A simple, tiny thing that every website has. But, in order to be compliant with different use cases, OS, Browsers, you need to have usually more than one - 16x16, 32x32, 180x180, 512x512, etc. It’s nice when you don’t need to care about it"),"\n",i.createElement(t.h3,{id:"and-with-gatsby-you-dont"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#and-with-gatsby-you-dont"},i.createElement(t.span,{className:"icon icon-link"})),"...and with Gatsby, you don’t"),"\n",i.createElement(t.p,null,"Change a single line in gatsby-config.js and upload png/jpg/svg based favicon...That’s it. Gatsby will generate a set of relevant icons following best practices optimizing the image without any additional work."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 41.379310344827594%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/ad241966e1c96273c344d6985efb6ebd/09400/compare2.webp 174w,\n/static/ad241966e1c96273c344d6985efb6ebd/3266f/compare2.webp 348w,\n/static/ad241966e1c96273c344d6985efb6ebd/657d2/compare2.webp 696w,\n/static/ad241966e1c96273c344d6985efb6ebd/e644e/compare2.webp 1044w,\n/static/ad241966e1c96273c344d6985efb6ebd/8daba/compare2.webp 1392w,\n/static/ad241966e1c96273c344d6985efb6ebd/01368/compare2.webp 3258w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/ad241966e1c96273c344d6985efb6ebd/88093/compare2.png 174w,\n/static/ad241966e1c96273c344d6985efb6ebd/91d18/compare2.png 348w,\n/static/ad241966e1c96273c344d6985efb6ebd/871fd/compare2.png 696w,\n/static/ad241966e1c96273c344d6985efb6ebd/4e07d/compare2.png 1044w,\n/static/ad241966e1c96273c344d6985efb6ebd/aeb15/compare2.png 1392w,\n/static/ad241966e1c96273c344d6985efb6ebd/32024/compare2.png 3258w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/ad241966e1c96273c344d6985efb6ebd/871fd/compare2.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",i.createElement(t.h3,{id:"but-what-about-nextjs"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#but-what-about-nextjs"},i.createElement(t.span,{className:"icon icon-link"})),"...but what about Next.js?"),"\n",i.createElement(t.p,null,"There is no opinionated way that Next.js recommends for this. ",i.createElement(t.a,{href:"https://www.google.com/search?q=next+js+favicon&rlz=1C5CHFA_enFR972FR972&oq=nextjs+favicon&aqs=chrome.1.69i57j0i10i67j0i10i512l2j0i10i22i30l3.4091j0j7&sourceid=chrome&ie=UTF-8"},"Try to Google it")," and see how different the answers are, e.g., this ",i.createElement(t.a,{href:"https://stackoverflow.com/questions/56213019/how-to-add-a-favicon-to-a-next-js-static-site"},"Stackoverflow Thread"),". Everything has to be done manually - image optimization, image resizing, embedding the proper tags using ",i.createElement(t.code,null,"<Head>")," tag. As an option, you can use favicons generators services like ",i.createElement(t.a,{href:"https://realfavicongenerator.net/"},"this"),"."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 55.7471264367816%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABRElEQVR42o2R65KCMAyFff/XW++i6KK0UEHsJUlT0A3q/tvR7XzDdEpOT0466W/DqczbrnXgHTjBgsNE9BaIQEyT2Mf9PtOVdt4zc2QOCMPtwxqGARknPPC5aZWqmqa9WouI938s0Yv/6BxTch4661xAATAipQAUkEfGTZRD+WKU1pJAzDi2ncYj+XHQOvs22cEsdnq+LZd5Pductsd2uVOLbbnO1Tw7Va2HmAJxoDi2Lc4ilvi5UtNMT1fFam++1sd5pmabUgRlfW2uoEx3sSBlvzzFD2frsaiNXKxN13TeXELdWKm2gcTLY3SPFH+IxwxRYqTUDwKnPvX9cxMFfkFj1Bfi95h2zxWYwp80VMAIgDLJT7O+I9EzM+fbdX02re3kkTFGerz2e6TMU5gM91tR5KpR9fWsLtqiI5Y89B6QQSX+AenheM4B0C/lAAAAAElFTkSuQmCC\'); background-size: cover; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/5abbb9cdf39d0d761567fd579e54bd3f/09400/compare3.webp 174w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/3266f/compare3.webp 348w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/657d2/compare3.webp 696w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/e644e/compare3.webp 1044w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/8daba/compare3.webp 1392w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/cfb0b/compare3.webp 1954w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/5abbb9cdf39d0d761567fd579e54bd3f/88093/compare3.png 174w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/91d18/compare3.png 348w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/871fd/compare3.png 696w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/4e07d/compare3.png 1044w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/aeb15/compare3.png 1392w,\n/static/5abbb9cdf39d0d761567fd579e54bd3f/d43d8/compare3.png 1954w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/5abbb9cdf39d0d761567fd579e54bd3f/871fd/compare3.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",i.createElement(t.h2,{id:"future-is-here-with-image-optimization"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#future-is-here-with-image-optimization"},i.createElement(t.span,{className:"icon icon-link"})),"Future is here with image optimization"),"\n",i.createElement(t.p,null,"Both do a lot of magic, tuning images with the sharp library, bringing the support for modern image file formats such as webp and avif, which results in smaller files’ sizes and a faster website loading speed."),"\n",i.createElement(t.p,null,"Both have their own image components, ",i.createElement(t.code,null,"next-image"),", and ",i.createElement(t.code,null,"gatsby-image"),", with a similar API. But there are a few differences."),"\n",i.createElement(t.h3,{id:"is-next-image-good"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#is-next-image-good"},i.createElement(t.span,{className:"icon icon-link"})),"Is next-image good?"),"\n",i.createElement(t.p,null,i.createElement(t.code,null,"next-image")," is just a component when the actual image optimization happens via API route that accepts query string parameters and returns a processed image, e.g., ",i.createElement(t.code,null,"/\\_next/image?url=http://example.com/avatar.png&w=32&h=32")),"\n",i.createElement(t.p,null,"I like this architecture for it also brings additional flexibility in terms of using optimized images without using a react component."),"\n",i.createElement(t.p,null,"Another thing worth mentioning: ",i.createElement(t.code,null,"next-image")," requires you to specify the width/height of the image, which is not the case when you fetch data from a CMS unless you use ",i.createElement(t.code,null,'layout="fill"'),", but having done that, you are required to manually handle the logic of the image wrapper. So to avoid layout shifts, you fetch the image from a CMS, get their width and height, then, for example, use a CSS aspect-ratio property or go with the SVG hack as ",i.createElement(t.code,null,"gatsby-image")," does automatically to maintain the original proportions"),"\n",i.createElement(t.h3,{id:"or-gatsby-image-is-better"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#or-gatsby-image-is-better"},i.createElement(t.span,{className:"icon icon-link"})),"or gatsby-image is better?"),"\n",i.createElement(t.p,null,i.createElement(t.code,null,"gatsby-image")," does not have that API endpoint and does the magic behind the scene using the power of their graphql data layer and different transformer plugins. Everything works out of the box without additional configuration. But there is one more thing that Gatsby can do better - ",i.createElement(t.a,{href:"https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image/#withartdirection"},"image art direction"),". Art direction aims to define multiple image srcsets for different screen sizes that could be cropped and positioned differently. The typical use case for this is when you have a big diagram, let’s say on the home page, but on mobile, it will be too small if we just scale it down. As a solution, you might pass a secondary image with increased diagram labels to the srcset optimized for mobile devices."),"\n",i.createElement(t.h2,{id:"importance-of-cms-integrations"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#importance-of-cms-integrations"},i.createElement(t.span,{className:"icon icon-link"})),"Importance of CMS Integrations"),"\n",i.createElement(t.p,null,"For the best customer experience, it’s precious to provide the greatest flexibility for editors and s
1olid CMS integration in place. On the websites, we build every word and page can be edited via CMS and any additional metadata - page URL, meta tags, og tags, etc. We use Headless WP most of the time, but sometimes do the job with Contentful, Strapi or Prismic, so having a flexible and straightforward way for data fetching from different platforms is crucial."),"\n",i.createElement(t.h3,{id:"gatsby-and-the-power-of-plugins"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#gatsby-and-the-power-of-plugins"},i.createElement(t.span,{className:"icon icon-link"})),"Gatsby and the power of plugins"),"\n",i.createElement(t.p,null,"With Gatsby, the integration is a matter of plugin installation and providing API keys. No need to deal with SDKs and nerding through API docs. Everything will be fetched and added to a unified Gatsby Graphql Layer. There are so many plugins that you can find a source plugin literally for anything. The client uses some recruiting platform and wants to display a jobs list on his own website as well? Not a problem. Does he plan to display a list of Github repositories with stars counter - just go and grab the plugin for this. Data will be added to Graphql, and you wouldn’t need to worry about the learning curve for understanding various APIs."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<figure class="gatsby-resp-image-figure" style="">\n    <span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 65.51724137931035%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/eb5a7e30f0a39522f4073f1287e49fb3/09400/compare4.webp 174w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/3266f/compare4.webp 348w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/657d2/compare4.webp 696w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/e644e/compare4.webp 1044w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/8daba/compare4.webp 1392w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/60405/compare4.webp 2906w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/eb5a7e30f0a39522f4073f1287e49fb3/88093/compare4.png 174w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/91d18/compare4.png 348w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/871fd/compare4.png 696w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/4e07d/compare4.png 1044w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/aeb15/compare4.png 1392w,\n/static/eb5a7e30f0a39522f4073f1287e49fb3/1fa8f/compare4.png 2906w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/eb5a7e30f0a39522f4073f1287e49fb3/871fd/compare4.png"\n            alt="Example of fetching data with Gatsby Graphql using gatsby-source-wordpress plugin"\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>\n    <figcaption class="gatsby-resp-image-figcaption">Example of fetching data with Gatsby Graphql using gatsby-source-wordpress plugin</figcaption>\n  </figure>'}}),"\n",i.createElement(t.h3,{id:"nextjs-tailored-approach"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#nextjs-tailored-approach"},i.createElement(t.span,{className:"icon icon-link"})),"Next.js tailored approach"),"\n",i.createElement(t.p,null,"Next.js does not have a plugins ecosystem, so for fetching data from a CMS, we have to find SDK, learn an API, think about the reusability of that integration within the website on different pages, probably make some SDK wrappers for common use cases, or HOC. Maybe it’s ok for small sites, but for large ones it will require spending some time thinking about the overall data fetching architecture and scalability of the solution."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 76.4367816091954%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/4f4206944ef5342008608a580de1d7a6/09400/compare5.webp 174w,\n/static/4f4206944ef5342008608a580de1d7a6/3266f/compare5.webp 348w,\n/static/4f4206944ef5342008608a580de1d7a6/657d2/compare5.webp 696w,\n/static/4f4206944ef5342008608a580de1d7a6/e644e/compare5.webp 1044w,\n/static/4f4206944ef5342008608a580de1d7a6/8daba/compare5.webp 1392w,\n/static/4f4206944ef5342008608a580de1d7a6/41d90/compare5.webp 2584w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/4f4206944ef5342008608a580de1d7a6/88093/compare5.png 174w,\n/static/4f4206944ef5342008608a580de1d7a6/91d18/compare5.png 348w,\n/static/4f4206944ef5342008608a580de1d7a6/871fd/compare5.png 696w,\n/static/4f4206944ef5342008608a580de1d7a6/4e07d/compare5.png 1044w,\n/static/4f4206944ef5342008608a580de1d7a6/aeb15/compare5.png 1392w,\n/static/4f4206944ef5342008608a580de1d7a6/bcbc8/compare5.png 2584w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/4f4206944ef5342008608a580de1d7a6/871fd/compare5.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",i.createElement(t.h2,{id:"to-preview-or-not-to-preview"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#to-preview-or-not-to-preview"},i.createElement(t.span,{className:"icon icon-link"})),"To preview or not to preview?"),"\n",i.createElement(t.p,null,"Okay, let’s step back here because I’m sure that many people don’t even bother themselves giving that functionality to the editors. Previews functionality means rendering a specific page on demand from a CMS without publishing it in the production."),"\n",i.createElement(t.p,null,"If you use Gatsby, it supports the most popular CMSs, and it works seamlessly. You can either use Gatsby Cloud, and the preview server will be created automatically, and all you will have to do is just point CMS to a correct URL, or you can deploy a self-hosted version running gatsby with ",i.createElement(t.code,null,"GATSBY_ENABLE_REFRESH_ENDPOINT=true"),". Below is an example of how it works with Gatsby + Headless WP."),"\n",i.createElement(a,{src:"https://pixel-point-website.s3.amazonaws.com/posts/2022-02-22-comparing-gatsby-and-nextjs-for-website-development/video.mp4",width:"1036",height:"720",controls:!0,muted:!0,poster:"./video-cover-1.jpg"}),"\n",i.createElement(t.p,null,"With Next.js, things yet again get more complicated; ",i.createElement(t.a,{href:"https://nextjs.org/docs/advanced-features/preview-mode"},"see the official doc"),". Again, there is a need to write it manually for every entity you plan to preview, defining rules of how the data from a preview trigger will be parsed, what will be fetched later, and what will be rendered. Instead of a five-minute setup with Gatsby, you will have to spend hours to get something usable."),"\n",i.createElement(t.h2,{id:"flexibility-for-editors-with-programmatic-page-generation"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#flexibility-for-editors-with-programmatic-page-generation"},i.createElement(t.span,{className:"icon icon-link"})),"Flexibility for editors with programmatic page generation"),"\n",i.createElement(t.h3,{id:"nextjs-options"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#nextjs-options"},i.createElement(t.span,{className:"icon icon-link"})),"Next.js options"),"\n",i.createElement(t.p,null,"To achieve the best-in-class editor experience, editors have to be in charge of defining URLs and pages displayed on it. Let’s break a rule and start from Next.js first. There are few options to achieve or partially achieve it."),"\n",i.createElement(t.ol,null,"\n",i.createElement(t.li,null,"\n",i.createElement(t.p,null,"Hardcode dynamic subpages URLs eg. ",i.createElement(t.code,null,"pages/post/[slug].js"),". For example, there is a slug field for a post on the CMS side, and you agree it will always be under the ",i.createElement(t.code,null,"/post"),", then define ",i.createElement(t.a,{href:"https://nextjs.org/docs/basic-features/data-fetching/get-static-paths"},"getStaticPaths")," in the component."),"\n"),"\n",i.createElement(t.li,null,"\n",i.createElement(t.p,null,"Write a wildcard component in the root ",i.createElement(t.code,null,"pages/[...path].js"),". Then write an additional wrapper component with the logic of mapping a specific URL to a specific component. It raises plenty of issues and increases the architecture complexity a lot."),"\n"),"\n",i.createElement(t.li,null,"\n",i.createElement(t.p,null,"Use ",i.createElement(t.a,{href:"https://faustjs.org/"},"Faust")," - a framework built based on Next.js tuned specifically for WP integration. Look at the source code, and you will find that they exactly do option 2) and see how complex it is. And it’s only available for WP."),"\n"),"\n"),"\n",i.createElement(t.h3,{id:"gatsby-way"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#gatsby-way"},i.createElement(t.span,{className:"icon icon-link"})),"Gatsby way"),"\n",i.createElement(t.p,null,"Gatsby originally has been created as a SSG framework, so it has a few powerful architecture concepts"),"\n",i.createElement(t.ol,null,"\n",i.createElement(t.li,null,"\n",i.createElement(t.p,null,"Single point of programmatic page generation in ",i.createElement(t.code,null,"gatsby-node.js"),". Imagine that it’s like telling the framework in a natural language - “Please fetch all pages from a CMS, then create for each CMS page a relevant Gatsby page based on a template and make it accessible on a URL defined in a CMS.” So here, we can use different templates for pages based on the data from a CMS."),"\n"),"\n",i.createElement(t.li,null,"\n",i.createElement(t.p,null,"Templates concepts. Separating Pages concept and Templates makes it easier to define hardcoded URLs and programmatically created pages based on templates."),"\n"),"\n"),"\n",i.createElement(t.p,null,"As a result, you can achieve entirely CMS-driven routes and pages creation without overwhelming yourself with complicated logic in the code."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 82.183908045977%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/be27b890b6d5282bdd0ecae1e2311d46/09400/compare6.webp 174w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/3266f/compare6.webp 348w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/657d2/compare6.webp 696w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/e644e/compare6.webp 1044w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/8daba/compare6.webp 1392w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/b98f3/compare6.webp 2994w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/be27b890b6d5282bdd0ecae1e2311d46/88093/compare6.png 174w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/91d18/compare6.png 348w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/871fd/compare6.png 696w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/4e07d/compare6.png 1044w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/aeb15/compare6.png 1392w,\n/static/be27b890b6d5282bdd0ecae1e2311d46/8f3ab/compare6.png 2994w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/be27b890b6d5282bdd0ecae1e2311d46/871fd/compare6.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",i.createElement(t.h2,{id:"we-demand-incremental-static-regeneration"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#we-demand-incremental-static-regeneration"},i.createElement(t.span,{className:"icon icon-link"})),"We demand Incremental Static Regeneration"),"\n",i.createElement(t.p,null,"Incremental Static Regeneration (ISR) allows you to update only specific pages incrementally instead of rebuilding all pages based on the incoming changes. Incremental builds are technically different from ISR, but both are trying to solve the same problem: speeding up content updates on a production by incrementally updating pages. Gatsby has been having incremental builds since v3 and actively uses it with the help of different CMS integrations and Gatsby Cloud by rebuilding only new updates, which usually takes mere seconds."),"\n",i.createElement(t.p,null,"Next.js had been following a bit different approach that did not require an additional build to run in case of CMS changes. Instead, it allowed you to specify the time in seconds for which the page will be fetched from a cache instead, so it will go and fetch new data when the first unlucky user comes in."),"\n",i.createElement(t.p,null,"Initially, I was considering putting it as a disadvantage for Next.js. It was a high-demand feature, but while I’ve been working on the article, they introduced on-demand ISR, which is supposed to solve the issue bringing the ability to revalidate cache from external sources calls. ",i.createElement(t.a,{href:"https://nextjs.org/blog/next-12-1#on-demand-incremental-static-regeneration-beta"},"As of the 17th of February, it is considered a Beta feature"),"."),"\n",i.createElement(t.h2,{id:"data-queries-everywhere"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#data-queries-everywhere"},i.createElement(t.span,{className:"icon icon-link"})),"Data queries everywhere"),"\n",i.createElement(t.p,null,"Another highly demanding feature of Next.js is query data similar to ",i.createElement(t.code,null,"getServerSideProps"),", ",i.createElement(t.code,null,"getStaticProps")," on a component level instead of just a parent page level. Currently, you have to use props drilling or stores/context to pass data from a top-level to an underneath component. React 18 and Server Side Component should potentially solve this issue in the future."),"\n",i.createElement(t.p,null,"Meanwhile, in a Gatsby project, you can fetch data from a global graphql layer from anywhere using ",i.createElement(t.code,null,"useStaticQuery"),". It simplifies the architecture and allows you to have reusable components."),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 75.86206896551725%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/e3791e0535e6ba7e0702edfbd560feed/09400/compare7.webp 174w,\n/static/e3791e0535e6ba7e0702edfbd560feed/3266f/compare7.webp 348w,\n/static/e3791e0535e6ba7e0702edfbd560feed/657d2/compare7.webp 696w,\n/static/e3791e0535e6ba7e0702edfbd560feed/e644e/compare7.webp 1044w,\n/static/e3791e0535e6ba7e0702edfbd560feed/8daba/compare7.webp 1392w,\n/static/e3791e0535e6ba7e0702edfbd560feed/24fa8/compare7.webp 2640w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/e3791e0535e6ba7e0702edfbd560feed/88093/compare7.png 174w,\n/static/e3791e0535e6ba7e0702edfbd560feed/91d18/compare7.png 348w,\n/static/e3791e0535e6ba7e0702edfbd560feed/871fd/compare7.png 696w,\n/static/e3791e0535e6ba7e0702edfbd560feed/4e07d/compare7.png 1044w,\n/static/e3791e0535e6ba7e0702edfbd560feed/aeb15/compare7.png 1392w,\n/static/e3791e0535e6ba7e0702edfbd560feed/84949/compare7.png 2640w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/e3791e0535e6ba7e0702edfbd560feed/871fd/compare7.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",i.createElement(t.h2,{id:"very-external-imports"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#very-external-imports"},i.createElement(t.span,{className:"icon icon-link"})),"Very external imports"),"\n",i.createElement(t.p,null,"This has been brought by NextJS recently and bear all signs of being a massive advantage in perspective, for combining Low-Code / No-Code solutions with hand-written applications. To understand this feature, it is best to read ",i.createElement(t.a,{href:"https://www.framer.com/docs/guides/handshake/"},"this great example")," of usage between Framer and Next.js. You can build a custom component in a visual editor, maybe also wrap it with some nice animations and then just import it to the project with a single line:"),"\n",i.createElement(t.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 696px; "\n    >
1\n      <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 43.10344827586207%; position: relative; bottom: 0; left: 0; display: block;"\n  ></span>\n  <picture>\n          <source\n              srcset="/static/09ffd115a0d89c83bed5030ab7f682a2/09400/compare8.webp 174w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/3266f/compare8.webp 348w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/657d2/compare8.webp 696w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/e644e/compare8.webp 1044w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/8daba/compare8.webp 1392w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/3105d/compare8.webp 1634w"\n              sizes="(max-width: 696px) 100vw, 696px"\n              type="image/webp"\n            />\n          <source\n            srcset="/static/09ffd115a0d89c83bed5030ab7f682a2/88093/compare8.png 174w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/91d18/compare8.png 348w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/871fd/compare8.png 696w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/4e07d/compare8.png 1044w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/aeb15/compare8.png 1392w,\n/static/09ffd115a0d89c83bed5030ab7f682a2/3b919/compare8.png 1634w"\n            sizes="(max-width: 696px) 100vw, 696px"\n            type="image/png"\n          />\n          <img\n            class="gatsby-resp-image-image"\n            src="/static/09ffd115a0d89c83bed5030ab7f682a2/871fd/compare8.png"\n            alt=""\n            title=""\n            loading="lazy"\n            decoding="async"\n            style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n          />\n        </picture>\n    </span>'}}),"\n",i.createElement(t.p,null,"This is mind-blowing and opens a lot of further possibilities. Gatsby does not allow you to do this at this moment. So if it’s something you want to use in your project, Next.js is probably a better option."),"\n",i.createElement(t.h2,{id:"sitemaps-are-good-everywhere"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#sitemaps-are-good-everywhere"},i.createElement(t.span,{className:"icon icon-link"})),"Sitemaps are good everywhere"),"\n",i.createElement(t.p,null,"Both frameworks can handle it by using additional libraries. Gatsby handles it with a plugin and minimal configuration. For Next.js, a ",i.createElement(t.a,{href:"https://www.npmjs.com/package/next-sitemap"},"library")," does the same but requires additional post-build script execution."),"\n",i.createElement(t.h2,{id:"smartless-i18n"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#smartless-i18n"},i.createElement(t.span,{className:"icon icon-link"})),"Smartless i18n"),"\n",i.createElement(t.p,null,"Interesting thing about this point that despite the fact that the implementation will look almost the same for both frameworks, another Next.js feature called ",i.createElement(t.a,{href:"https://nextjs.org/docs/middleware"},"Global Middlewares")," makes it much more powerful. It allows you to define a top-level middleware and perform, let’s say, a country detection on an edge network and than either replacing or redirecting user to a statically generated page."),"\n",i.createElement(t.h2,{id:"summary"},i.createElement(t.a,{"aria-hidden":"true",tabIndex:"-1",href:"#summary"},i.createElement(t.span,{className:"icon icon-link"})),"Summary"),"\n",i.createElement(t.p,null,"We can still recommend both frameworks for website development as very reliable solutions. However, Gatsby definitely works better in terms of static generation and integrations made possible by the plugin ecosystem. For us those features are critical and we see how Gatsby allows us to build websites faster, make them flexible and maintainable. Next.js is a more dynamic-oriented framework, and I would go for it only if I need an additional auth layer on the website or maybe in case when I need that Global Middleware functionality that could help deal with i18n, A/B testing, or Feature Flags. These are definitely nice to have, but usually, they are only required for a huge enterprise-grade tech where you can afford such experiments."))}var o=function(e){void 0===e&&(e={});const{wrapper:t}=Object.assign({},(0,n.RP)(),e.components);return t?i.createElement(t,e,i.createElement(s,e)):s(e)};var r=a(2532),c=a(1021),l=a(545),d=a(9072),p=a(3669),m=a(9063),b=a(352),g=a(84);const f=e=>{let{data:{mdx:{author:t,frontmatter:a,fields:{slug:n}},allMdx:{nodes:s}},location:o,pageContext:{videoCovers:r},children:b}=e;return i.createElement(m.A,{headerTheme:"black",headerShowThemeButton:!0},i.createElement("article",{className:"safe-paddings pt-32 sm:pt-24"},i.createElement("div",{className:"container"},i.createElement("div",{className:"relative mx-auto max-w-[696px] xl:mx-0 xl:flex xl:max-w-none xl:justify-center xl:space-x-20 lg:space-x-8 md:block md:space-x-0"},i.createElement("div",{className:"xl:max-w-[696px] lg:max-w-[626px] md:max-w-none"},i.createElement(l.A,Object.assign({},a,{slug:n})),i.createElement(c.A,{content:b,videoCovers:r})),i.createElement(d.A,{author:t,readMorePosts:s,socialShareUrl:o.href})))),i.createElement(p.A,{withTopMargin:!0}))};function h(e){return i.createElement(f,e,i.createElement(o,e))}const u=e=>{let{data:{mdx:{frontmatter:{title:t,summary:a,ogImage:n}}}}=e;const s=(0,r.d)(n);return i.createElement(b.A,g.A.blogPost({title:t,description:a,ogImage:s}))}}}]);
2//# sourceMappingURL=component---src-templates-blog-post-jsx-content-file-path-content-posts-2022-02-22-comparing-gatsby-and-nextjs-for-website-development-index-md-87499bc7f5ec0c81f670.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.