<?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: Jamie Bradley</title>
    <description>The latest articles on Forem by Jamie Bradley (@jamiebradley).</description>
    <link>https://forem.com/jamiebradley</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%2F261872%2Fe681f12b-523d-40ed-a022-95454b793843.jpeg</url>
      <title>Forem: Jamie Bradley</title>
      <link>https://forem.com/jamiebradley</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jamiebradley"/>
    <language>en</language>
    <item>
      <title>Laravel 12 and new starter kits are released today 🤘 anyone else excited?</title>
      <dc:creator>Jamie Bradley</dc:creator>
      <pubDate>Mon, 24 Feb 2025 07:51:44 +0000</pubDate>
      <link>https://forem.com/jamiebradley/laravel-12-and-new-starter-kits-are-being-released-today-anyone-else-excited-2459</link>
      <guid>https://forem.com/jamiebradley/laravel-12-and-new-starter-kits-are-being-released-today-anyone-else-excited-2459</guid>
      <description></description>
      <category>laravel</category>
      <category>news</category>
    </item>
    <item>
      <title>The Developer's Guide to Physical and Mental Well-being</title>
      <dc:creator>Jamie Bradley</dc:creator>
      <pubDate>Sat, 22 Feb 2025 20:38:15 +0000</pubDate>
      <link>https://forem.com/jamiebradley/become-a-healthy-developer-to-be-a-better-developer-4b8k</link>
      <guid>https://forem.com/jamiebradley/become-a-healthy-developer-to-be-a-better-developer-4b8k</guid>
      <description>&lt;p&gt;I stumbled across a &lt;a href="https://www.instagram.com/theescapingnormalguy/p/DATZi_gzJ_f/" rel="noopener noreferrer"&gt;post on Instagram&lt;/a&gt; that promoted an anonymous quote.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A healthy body is a healthy mind and a healthy mind takes care of business&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it's a powerful quote. It's accurate and I can resonate with it. Before 2024, my physical and mental health were terrible. I had a bad diet, I barely moved and I was constantly stressed. &lt;/p&gt;

&lt;p&gt;In 2024 I went on a journey that changed my life. I want to write about what I learned in the hope that others can hear my perspective and maybe change their lives too. &lt;/p&gt;

&lt;h2&gt;
  
  
  Start with Step Count
&lt;/h2&gt;

&lt;p&gt;If you're reading this post on dev.to then it's fair to assume that you work in the tech industry. I assume you spend the majority of the working day at a desk. A percentage of readers might have access to a standing desk with a treadmill - go you 🤘&lt;/p&gt;

&lt;p&gt;With that in mind, have you considered how many steps you walk in a day?&lt;/p&gt;

&lt;p&gt;I'm 35 years old. Websites I found on Google say that a person of my age should be walking between 6,000-10,000 steps a day. Most days I manage to hit this number. But prior to 2024 &lt;strong&gt;I was lucky if I walked 1,000 steps&lt;/strong&gt; and that was "normal" for me. &lt;/p&gt;

&lt;p&gt;This attitude was destroying my body.&lt;/p&gt;

&lt;p&gt;The NHS claims that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Studies have linked being inactive with being overweight and obese, type 2 diabetes, some types of cancer, and early death.&lt;/p&gt;

&lt;p&gt;Sitting for long periods is thought to slow the metabolism, which affects the body's ability to regulate blood sugar, blood pressure and break down body fat.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Extract taken from the Live Well post &lt;a href="https://www.nhs.uk/live-well/exercise/why-sitting-too-much-is-bad-for-us/" rel="noopener noreferrer"&gt;"Why we should sit less"&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So if these numbers feel "normal" to you too. It's time to take some action.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's not just Physical Health
&lt;/h2&gt;

&lt;p&gt;A sedentary lifestyle contributes to poor mental health too. If we spend long periods of time indoors, especially with little movement, we deprive ourselves on sunlight and fresh air. &lt;/p&gt;

&lt;p&gt;Sunlight triggers the production of Vitamin D and the release of a hormone called serotonin both of which are associated with improving your mood, focus and reducing stress.&lt;/p&gt;

&lt;p&gt;Exercising releases a cocktail of amazing hormones, one being the "feel good" hormone - Dopamine. That's right! If you're feeling like crap then taking a break and exercising will make you feel better. I can vouch for this!&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm too busy to exercise
&lt;/h2&gt;

&lt;p&gt;I'm the co-founder of a small agency in the UK. Starting the business was tough. I worked very long hours and prioritised work before so many things, including my health.&lt;/p&gt;

&lt;p&gt;I managed to convince myself that if I wasn't working long hours then my business would fail. But it didn't occur to me that if I was more productive and focused, I wouldn't need to work late every night.&lt;/p&gt;

&lt;p&gt;Being tired also contributed to a load of mistakes. The quality of my work was not to my usual standard and I was beginning to doubt my ability. It became a vicious cycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  It only takes 30 minutes
&lt;/h3&gt;

&lt;p&gt;As the last title suggests, my excuse for not exercising was "I'm too busy". I believed that taking time away from a task would result in less time to finish the task.&lt;/p&gt;

&lt;p&gt;Eventually I realised that all I needed was thirty minutes of &lt;em&gt;something&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Taking a walk&lt;/li&gt;
&lt;li&gt;Going for a jog&lt;/li&gt;
&lt;li&gt;Riding a bicycle&lt;/li&gt;
&lt;li&gt;Lifting some weights&lt;/li&gt;
&lt;li&gt;Following a workout video&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also told myself that I could only do one of these things on my lunch break. I couldn't wake up early because I was tired from a late night of working. I couldn't workout when I got home, because I "needed" to be back on the laptop.&lt;/p&gt;

&lt;p&gt;All it took was 30 minutes. Everyone can find 30 minutes in their day. We probably spend more than 30 minutes scrolling through TikTok and Instagram!&lt;/p&gt;

&lt;h3&gt;
  
  
  My Solution
&lt;/h3&gt;

&lt;p&gt;This won't work for everyone. But my solution was to wake up at 6am and attend a spinning class at the local gym. The spinning class was a high intensity session, so it only lasted 30 minutes, but damn it worked you hard!&lt;/p&gt;

&lt;p&gt;Waking up early and working out in the morning meant I was using more energy. I needed to make time for sleep. I changed my routine to make sure I was asleep by no later than 10pm. This meant I was guaranteed at least 8 hours sleep.&lt;/p&gt;

&lt;p&gt;Given that the recommended number of hours for an adult is 7-9 hours, this worked well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stay Consistent
&lt;/h2&gt;

&lt;p&gt;Over the last 10 years I had been very inconsistent when it came to diet and exercise. I would do well for a few weeks but then fall of the wagon. I think it was because I would set unrealistic expectations. &lt;/p&gt;

&lt;p&gt;This time I have always reminded myself "it's just half an hour of something".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basically. You need to just show up.&lt;/strong&gt; Whether it's at the gym, running around the block or going for a walk to a coffee shop and back. Remember that something is better than staying inside, sat down, doing nothing.&lt;/p&gt;

&lt;p&gt;The benefits will follow. &lt;/p&gt;

&lt;p&gt;Today, I am 10kg lighter than I was in January 2024. My cardiovascular health is better, my blood pressure and cholesterol levels have dropped. I am training for a half marathon, and a year ago I couldn't run around the corner without being breathless.&lt;/p&gt;

&lt;p&gt;Finally, my mental health has significantly improved. I deal with high pressure situations better than before. I'm more focused and attentive with coding and I'm happier with the applications I build. &lt;/p&gt;

&lt;p&gt;People have told me they see a difference in my mood. Which must mean I'm a better person to be around 😂&lt;/p&gt;

&lt;p&gt;Being a healthier developer made me a better developer.&lt;/p&gt;




&lt;p&gt;What are your thoughts on the importance of health and working in tech? Have you embarked on a similar journey and noticed the same improvements? Leave a comment below and let's spark a discussion.&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>workplace</category>
      <category>startup</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Headless Ecommerce Tutorial with (Sanity and) the Shopify API</title>
      <dc:creator>Jamie Bradley</dc:creator>
      <pubDate>Wed, 09 Jun 2021 22:45:56 +0000</pubDate>
      <link>https://forem.com/sanity-io/headless-ecommerce-tutorial-with-sanity-and-the-shopify-api-1kpi</link>
      <guid>https://forem.com/sanity-io/headless-ecommerce-tutorial-with-sanity-and-the-shopify-api-1kpi</guid>
      <description>&lt;p&gt;One of my favorite things about Jamstack is the ability to drip-feed third-party services into your website through APIs. We have seen a huge increase in "headless" content services, such as Sanity, but today I want to talk about headless commerce.&lt;/p&gt;

&lt;p&gt;Headless commerce, much like a headless CMS, is the process of abstracting your front end away from a monolithic e-commerce system (such as Shopify). So instead of creating a Shopify Theme, you can create a website in Next, Gatsby, Nuxt, 11ty, vanilla javascript...anything that can consume an API!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why should you use a headless e-commerce system?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As developers, we get a better experience. We can develop websites with tools we are most comfortable with, rather than being constrained to a platform's theming standards.&lt;/p&gt;

&lt;p&gt;With this flexibility, our user also gets a better experience. We can use the likes of Jamstack to deliver fast, secure, and scalable websites.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What we'll be building today&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this article, we are going to create a website with Next.js. We will create a headless Shopify Store using &lt;a href="https://shopify.dev/docs/storefront-api" rel="noopener noreferrer"&gt;Shopify's Storefront API&lt;/a&gt; and combine this with data from an instance of Sanity.&lt;/p&gt;

&lt;p&gt;Our end product will be an online store that contains content (that is managed through Sanity) and a list of products from a "Featured" collection. Each product will contain a "Buy Now" button that will take our customers straight to a checkout that is generated by the Storefront API.&lt;/p&gt;

&lt;p&gt;You can find the repository for the end product &lt;a href="https://github.com/JamieBradders/Shopify-Sanity-Next-Example" rel="noopener noreferrer"&gt;here&lt;/a&gt; and a hosted example &lt;a href="https://shopify-sanity-next-example.vercel.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's install Next.js
&lt;/h2&gt;

&lt;p&gt;Before we get hands-on with code, we need to start by setting up the tools that we will use for this project. We're going to use Next.js to develop the front-end layer of our app, so we'll start there.&lt;/p&gt;

&lt;p&gt;The quickest way to get started with Next.js is to use &lt;code&gt;create-next-app&lt;/code&gt;. Start by creating an empty folder. Next, navigate to the new folder in your terminal and run one of the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn create next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;Psst: Don't have Node or NPM installed? There are some &lt;a href="https://www.sanity.io/help/a5f6caba-53c9-4a9f-96ef-1bd1ae8f5c10" rel="noopener noreferrer"&gt;great instructions here&lt;/a&gt; to help you get started with installing Node and NPM on your computer.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;The &lt;code&gt;create-next-app&lt;/code&gt; tool will ask you to provide a name for your Next App. For the purpose of this guide, please call it &lt;code&gt;web&lt;/code&gt;. Once &lt;code&gt;create-next-app&lt;/code&gt; is complete, you should have a file structure similar to the screenshot below:&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%2Ffgoflij1q5syl178v7bj.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%2Ffgoflij1q5syl178v7bj.png" alt="A screenshot showing the options presented to you when running sanity init" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Spicing up styles with Tailwind
&lt;/h3&gt;

&lt;p&gt;The examples in this guide include components that have been developed with Tailwind CSS. Please follow the &lt;a href="https://tailwindcss.com/docs/guides/nextjs#setting-up-tailwind-css" rel="noopener noreferrer"&gt;latest instructions from Tailwind's website here&lt;/a&gt; to install Tailwind in your Next.js application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with Sanity
&lt;/h2&gt;

&lt;p&gt;With the front-end ready to go our next job is to create a local instance of Sanity's Studio. This is the application we will use to manage page content outside of Shopify.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the studio
&lt;/h3&gt;

&lt;p&gt;The best way to get started with Sanity is to use Sanity's CLI tool. If you don't already have this, you can install the tool by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @sanity/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon completion of the installation, you will have access to a new terminal command called &lt;code&gt;sanity&lt;/code&gt; - you can run &lt;code&gt;sanity help&lt;/code&gt; to see a list of available commands from this tool.&lt;/p&gt;

&lt;p&gt;To create a new studio, run &lt;code&gt;sanity init&lt;/code&gt; after running this command you should see something like this:&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%2F4fbjpqjetzjkeulimmn9.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%2F4fbjpqjetzjkeulimmn9.png" alt="A screenshot showing a list of Sanity Studio templates" width="800" height="668"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: If you aren't already logged into your Sanity account then you will be asked to log in or create an account with Sanity before seeing these options.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Select &lt;code&gt;Create new project&lt;/code&gt; from the list of options and give your project a name (this is name that will be allocated to your project in the your Sanity Account dashboard).&lt;/p&gt;

&lt;p&gt;Next, you will be asked about datasets. For the purpose of this guide you can go ahead and use Sanity's default configuration by entering &lt;code&gt;Y&lt;/code&gt; then pressing enter.&lt;/p&gt;

&lt;p&gt;Sanity will now ask you for a Project Output Path. To stay in line with this guide, enter the word &lt;code&gt;studio&lt;/code&gt; and hit enter. You will see that Sanity has updated the Project Output Path to use the folder name &lt;code&gt;studio&lt;/code&gt; as per the screenshot below:&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%2Fkvj09f9331uhh5xkghd4.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%2Fkvj09f9331uhh5xkghd4.png" alt="A screenshot showing a list of Sanity Studio templates" width="800" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, when presented with the Project Template options, please select the &lt;code&gt;Clean project with no predefined schemas&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;After selecting this option, Sanity will proceed with the installation and initialisation of the studio. Once this is complete you should now have a project folder with a structure like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;web/
  .git
  .gitignore
  README.md
  node_modules/
  package.json
  pages/
  public/
  styles/
  yarn.lock

studio/
  README.md
  config/
  node_modules/
  package.json
  plugins/
  sanity.json
  schemas/
  static/
  tsconfig.json
  yarn.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Let's build the Schema&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before we start working on the Next.js code we're going to dive into Sanity and set up the schema for our website. The primary focus for this tutorial is the homepage, so we're going to create a singleton document (or "one-off"). This is a great opportunity to see Sanity's flexibility with the &lt;a href="https://www.sanity.io/docs/structure-builder-typical-use-cases" rel="noopener noreferrer"&gt;Structure Builder&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First we need to create the homepage document. Start by creating a file called &lt;code&gt;homepage.js&lt;/code&gt; within your &lt;code&gt;studio/schemas&lt;/code&gt; folder. Take the contents of this snippet and add it to the &lt;code&gt;homepage.js&lt;/code&gt; 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="c1"&gt;// studio/schemas/homepage.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;homepage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Homepage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;// These actions define what users can do with this document.&lt;/span&gt;
  &lt;span class="c1"&gt;// Notice how "delete" is not available in this array.&lt;/span&gt;
  &lt;span class="c1"&gt;// This means, users can't delete this document&lt;/span&gt;
  &lt;span class="c1"&gt;// from within the studio&lt;/span&gt;
  &lt;span class="na"&gt;__experimental_actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;update&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;create&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;publish&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="na"&gt;fields&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hero Title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&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 title will appear in the hero unit at the top of the page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;heroTitle&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;Next, we need to tell Sanity to include the &lt;code&gt;homepage&lt;/code&gt; document within the Studio's schema. We can do this by importing the new object into &lt;code&gt;studio/schemas/schema.js&lt;/code&gt; and appending it to the &lt;code&gt;schemaTypes&lt;/code&gt; array like so:&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;// studio/schemas/schema.js&lt;/span&gt;

&lt;span class="c1"&gt;// First, we must import the schema creator&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createSchema&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;part:@sanity/base/schema-creator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Then import schema types from any plugins that might expose them&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;schemaTypes&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;all:part:@sanity/base/schema-type&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;homepage&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;./homepage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Then we give our schema to the builder and provide the result to Sanity&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;createSchema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// We name our schema&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Then proceed to concatenate our document type&lt;/span&gt;
  &lt;span class="c1"&gt;// to the ones provided by any plugins that are installed&lt;/span&gt;
  &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;schemaTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="cm"&gt;/* Your types here! */&lt;/span&gt;
    &lt;span class="nx"&gt;homepage&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;Before we look at the structure builder, let's take this opportunity to make sure everything is working. If you haven't already, run &lt;code&gt;sanity start&lt;/code&gt; from your studio's directory in the terminal and navigate to &lt;a href="http://localhost:3333" rel="noopener noreferrer"&gt;localhost:3333&lt;/a&gt; in your browser. If all is well, you should see a screen similar to the screenshot below.&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%2Fslrzsnttkq5rl07n0ksp.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%2Fslrzsnttkq5rl07n0ksp.png" alt="A screenshot of the Sanity Studio" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is great, but to give our editor the required behavior for managing a "one-off" document, we need to modify the Desk tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Defining Parts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is a &lt;a href="https://www.sanity.io/docs/parts" rel="noopener noreferrer"&gt;fantastic Sanity guide&lt;/a&gt; about the parts system. For now, all we need to know is that we are going to use this system to customise our Desk.&lt;/p&gt;

&lt;p&gt;From the &lt;code&gt;studio&lt;/code&gt; folder, open &lt;code&gt;sanity.json&lt;/code&gt; and take a look at the parts array, it should look something like this:&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;// studio/sanity.json&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;part:@sanity/base/schema&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./schemas/schema&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, the studio uses the schema part to read our schema definitions that we declare in &lt;code&gt;schema.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We're now going to add an extra object to this array like so:&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;// studio/sanity.json&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;part:@sanity/base/schema&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./schemas/schema&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;part:@sanity/desk-tool/structure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./deskStructure.js&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to create the file that we will use to define our desk structure. This will be a file called &lt;code&gt;deskStructure.js&lt;/code&gt; that is located in the root of our &lt;code&gt;studio&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Let's create that file and include the following code:&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;// studio/deskStructure.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;S&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;@sanity/desk-tool/structure-builder&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="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Menu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Homepage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;homepage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schemaType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;homepage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;documentId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;homepage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Homepage&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="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;documentTypeListItems&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;homepage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getId&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;Here, we are importing the Sanity Structure Builder package. We use this package to define what we want to display in the Desk view. More specifically, we are using the &lt;code&gt;listItem()&lt;/code&gt; method to replace the default list item for the homepage document with a custom one. For instance, we can modify the title and customize some of the editor properties for this document type.&lt;/p&gt;

&lt;p&gt;Restart the local Sanity dev server and head back to your Studio. You should see a page similar to the one from the screenshot below.&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%2Fpr1uohiydgth18t5lu29.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%2Fpr1uohiydgth18t5lu29.png" alt="A screenshot of the Sanity Studio" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before moving on to integrating Sanity with Next, open your studio, and add add a title to the homepage document.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Building the Homepage&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We're going to set up a dedicated file that will be used to handle the fetching of data from Sanity.&lt;/p&gt;

&lt;p&gt;First, let's navigate to our &lt;code&gt;web&lt;/code&gt; folder and install the next-sanity package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## Run this command from the web/ directory! ##&lt;/span&gt;

&lt;span class="c"&gt;# NPM&lt;/span&gt;
npm i next-sanity

&lt;span class="c"&gt;# Yarn&lt;/span&gt;
yarn add next-sanity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new folder within the &lt;code&gt;web&lt;/code&gt; directory called &lt;code&gt;lib/&lt;/code&gt;. Within this folder, create a file called &lt;code&gt;sanity.js&lt;/code&gt; and insert the following code:&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;// web/lib/sanity.js&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;groq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;,&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-sanity&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;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * Find your project ID and dataset in `sanity.json` in your studio project.
   * These are considered “public”, but you can use environment variables
   * if you want differ between local dev and production.
   *
   * https://nextjs.org/docs/basic-features/environment-variables
   **/&lt;/span&gt;

  &lt;span class="na"&gt;dataset&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;NEXT_PUBLIC_SANITY_DATASET&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;projectId&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;NEXT_PUBLIC_SANITY_PROJECT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useCdn&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;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * Set useCdn to `false` if your application require the freshest possible
   * data always (potentially slightly slower and a bit more expensive).
   * Authenticated request (like preview) will always bypass the CDN
   **/&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Set up the client for fetching data in the getProps page functions&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;sanityClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Set up a preview client with serverless authentication for drafts&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;previewClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useCdn&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="na"&gt;token&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;SANITY_API_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Helper function for easily switching between normal client and preview client&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;getClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;usePreview&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;usePreview&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;previewClient&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sanityClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we are referencing some environment variables here. You will need to create a file called &lt;code&gt;.env.local&lt;/code&gt; that includes the following variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# web/.env.local&lt;/span&gt;

&lt;span class="nv"&gt;NEXT_PUBLIC_SANITY_PROJECT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;project-id&amp;gt;"&lt;/span&gt;
&lt;span class="nv"&gt;SANITY_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;token&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to replace the values with a project ID and API token. Both of these can be retrieved from your Sanity project dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For more information on next-sanity and the api.js file, take a look at the &lt;a href="https://github.com/sanity-io/next-sanity" rel="noopener noreferrer"&gt;Github repository for next-sanity&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Writing the Markup &amp;amp; Mapping Content&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Go to your &lt;code&gt;web&lt;/code&gt; folder and open &lt;code&gt;pages/index.js&lt;/code&gt;, replace the content with the following:&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;// web/pages/index.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&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/image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&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/link&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;groq&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-sanity&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;getClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../lib/sanity&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;homepageQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;groq&lt;/span&gt;&lt;span class="s2"&gt;`*[_type == "homepage"]{
  heroTitle
}[0]`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HomePage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&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;homepageData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&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;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-50"&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-96 bg-indigo-500 flex justify-center items-center"&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;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-white font-semibold text-6xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;homepageData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;heroTitle&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;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;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;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"container mx-auto py-12"&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;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-semibold text-4xl mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Featured Products&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid grid-flow-row grid-cols-3 grid-rows-auto gap-8"&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;article&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-center bg-white rounded-xl p-8 md:p-0 shadow-md pt-6 md:p-8 space-y-8"&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;Image&lt;/span&gt;
              &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://images.pexels.com/photos/218763/pexels-photo-218763.jpeg?auto=compress&amp;amp;cs=tinysrgb&amp;amp;dpr=2&amp;amp;h=750&amp;amp;w=1260"&lt;/span&gt;
              &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"150"&lt;/span&gt;
              &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"150"&lt;/span&gt;
              &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"A pair of slippers"&lt;/span&gt;
              &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rounded-full"&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-semibold text-2xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;A Pair of Slippers&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;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-medium"&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;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-100 text-gray-800 px-6 py-2 rounded block"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  View Product
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&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;Link&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;article&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&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;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;HomePage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&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;homepageData&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;getClient&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;homepageQuery&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;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;homepageData&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this code, we are using the Next.js &lt;code&gt;getStaticProps&lt;/code&gt; method to retrieve data from Sanity at build time. The data we retrieve is assigned to a property called &lt;code&gt;homepageData&lt;/code&gt;. We send this property to our page component as part of a prop called &lt;code&gt;data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since we are using Next Image, you will need to allow Next to download the placeholder image from &lt;a href="https://images.pexels.com" rel="noopener noreferrer"&gt;https://images.pexels.com&lt;/a&gt;. Whilst we are here, we will tell Next.js to download images from Shopify, this will be useful later.&lt;/p&gt;

&lt;p&gt;You can do this by creating a file called &lt;code&gt;next.config.js&lt;/code&gt; and entering the following code:&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;// web/next.config.js&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;images.pexels.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cdn.shopify.com&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start your application by running &lt;code&gt;next dev&lt;/code&gt; or the dev script in &lt;code&gt;package.json&lt;/code&gt; (from within the &lt;code&gt;web/&lt;/code&gt; directory) and you should see a page that looks very similar to the screenshot below.&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%2Fb2x5y9q39eynkdg6xx0f.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%2Fb2x5y9q39eynkdg6xx0f.png" alt="A screenshot of the Next.js store front" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to retrieve data from Shopify
&lt;/h2&gt;

&lt;p&gt;First, we need to get a Storefront Access Token from Shopify. If you already have a Storefront token, with the correct permissions, then feel free to skip this step.&lt;/p&gt;

&lt;p&gt;You will need access to a Shopify store. A live store will work fine, but if you're just playing around then I would suggest creating a development store.&lt;/p&gt;

&lt;p&gt;You can create a development store with a &lt;a href="https://www.shopify.co.uk/partners" rel="noopener noreferrer"&gt;Shopify Partner Account&lt;/a&gt;. If you don't have an account then &lt;a href="https://partners.shopify.com/signup" rel="noopener noreferrer"&gt;click here to register&lt;/a&gt;. Creating a Partners Account means that you will have access to a fully featured store without having to sign up for a free trial.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting a Shopify Storefront Access Token
&lt;/h3&gt;

&lt;p&gt;Once you have access to a store, you need to log into the Shopify Admin and create a Shopify App. You can do this by visiting your store's URL (which will look like &lt;a href="https://your-store-name.myshopify.com/admin" rel="noopener noreferrer"&gt;https://your-store-name.myshopify.com/admin&lt;/a&gt;) and clicking on the "Apps" link from the left-hand navigation bar. This will take you to the Apps page. Scroll to the bottom of this page and locate the following text "Working with a developer on your shop? Manage private apps", click "Manage private apps".&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%2Fb6sbhezppz4pt307m1br.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%2Fb6sbhezppz4pt307m1br.png" alt="A screenshot showing the 'manage private apps' link" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you have not created a Private App on this store before, you will be asked a series of questions regarding terms and conditions surrounding Private Apps on Shopify. You will have to agree to the terms before continuing.&lt;/p&gt;

&lt;p&gt;If all is well you will be presented with the Private Apps page. Click on the button labeled "Create new private app" which is situated at the top right-hand side of the page.&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%2Fb8rsm0vmtabfgg03trtb.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%2Fb8rsm0vmtabfgg03trtb.png" alt="A screenshot displaying the 'Create new private app' button" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill out the fields in the "App Details" section, then scroll to the bottom of the page and look for a checkbox with a label that contains the text "Allow this app to access your storefront data using the Storefront API". Then, click this checkbox.&lt;/p&gt;

&lt;p&gt;Selecting this checkbox tells Shopify that you intend to use the Storefront API as part of your private app. Ensure the following permissions are selected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read products, variants, and collections

&lt;ul&gt;
&lt;li&gt;Read product tags&lt;/li&gt;
&lt;li&gt;Read inventory of products and their variants&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Read and modify checkouts&lt;/li&gt;

&lt;/ul&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%2Fvgaci8tffxv5bpr9tsc0.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%2Fvgaci8tffxv5bpr9tsc0.png" alt="A screenshot showing the Storefront API permissions" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have selected these options, click the save button located at the top right-hand side of the screen.&lt;/p&gt;

&lt;p&gt;If all is well, the page will refresh. Scroll to the bottom of the private app page and locate the "Storefront API" section. At the bottom of this section, you will see a text field labeled "Storefront access token". We will use this access token to handle authentication with the Shopify Storefront API, so keep this page open.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Add products to Shopify&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At the moment, our homepage is returning a single product card that contains hardcoded data. In this part of the tutorial, we're going to add a product to our instance of Shopify and assign it to a collection.&lt;/p&gt;

&lt;p&gt;In Shopify, a collection is a group of products. You can assign many products to a collection and a product can be assigned to more than one collection.&lt;/p&gt;

&lt;p&gt;Head over to your instance of Shopify and click the "Products" link that is located in the navigation bar on the left hand side.&lt;/p&gt;

&lt;p&gt;If you have no products in your store, then go ahead and add some. For the purpose of this demonstration I have created a single product with no variants.&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%2Fkmhly90flwddtgb0qiyo.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%2Fkmhly90flwddtgb0qiyo.png" alt="A screenshot of Products in the Shopify Admin App" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the products have been added, we need to create a collection. Click on the "Collections" link from the sidebar.&lt;/p&gt;

&lt;p&gt;Give your collection the name of "Homepage" and scroll down to the Collection Type section. Shopify gives you the ability to create automated collections. This is a pretty cool feature that you can &lt;a href="https://help.shopify.com/en/manual/products/collections/automated-shopify-collection" rel="noopener noreferrer"&gt;read more about here&lt;/a&gt;. But, for the purpose of this tutorial, we are going to create a Manual collection.&lt;/p&gt;

&lt;p&gt;Select the radio button labelled "Manual collection".&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%2Fwg2p79omwc1y6okgv9lo.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%2Fwg2p79omwc1y6okgv9lo.png" alt="A screenshot showing Collection Types in Shopify Admin" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have done this, ensure the Private App you created earlier is selected within the "Collection availability" section at the top of the page. If this option is un-checked, then you won't be able to request the collection from the API.&lt;/p&gt;

&lt;p&gt;Save the collection and wait for the page to reload. You will now see a section called "Products". In this section, you can locate products from your store's inventory and assign them to the collection.&lt;/p&gt;

&lt;p&gt;Go ahead and search for the products you created earlier. Add them to the collection and wait for the collection to update (this should happen asynchronously as you add products).&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%2Fzsltzvenv4l12r3j5ds0.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%2Fzsltzvenv4l12r3j5ds0.png" alt="A screenshot showing Products in the collection editor" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Displaying products in Next.js&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As we did with the Sanity content, we now need to map the products from Shopify into our homepage. This process is very similar to what we did earlier. However, unlike Shopify Admin's REST API, the Storefront API is a GraphQL API. This means we need to write API queries with the GraphQL syntax.&lt;/p&gt;

&lt;p&gt;Let's start by installing some new dependencies.&lt;/p&gt;

&lt;p&gt;We're going to install a package called &lt;code&gt;graphql-request&lt;/code&gt;. This is a minimal GraphQL client that can be used in both Node and browser based environments. Install the package with NPM or Yarn respectively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Run this from the web/ folder! ##

# NPM
npm i graphql-request graphql

# Yarn
yarn add graphql-request graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we write some GraphQL queries, it would be a good idea to store our Shopify Endpoint URL and access token as environment variables. Your URL will look something like this: &lt;a href="https://your-store-name.myshopify.com" rel="noopener noreferrer"&gt;https://your-store-name.myshopify.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;.env.local&lt;/code&gt; file that you created earlier and include the following variables. Be sure to replace my placeholder values with your actual values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# web/.env.local

# Shopify Config
NEXT_PUBLIC_SHOPIFY_URL="replace-with-url"
NEXT_PUBLIC_TOKEN="replace-with-token"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your dev server after making the changes and head back to the &lt;code&gt;pages/index.js&lt;/code&gt; file to import the new dependencies.&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;// web/pages/index.js&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;gql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLClient&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;graphql-request&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;Now, we're going to make the following changes to &lt;code&gt;getStaticProps()&lt;/code&gt;. This is where we will use our new environment variables.&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;// web/pages/index.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&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;homepageData&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;getClient&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;homepageQuery&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;graphQLClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GraphQLClient&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;NEXT_PUBLIC_SHOPIFY_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Shopify-Storefront-Access-Token&lt;/span&gt;&lt;span class="dl"&gt;"&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;NEXT_PUBLIC_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;span class="c1"&gt;// Shopify Request&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
    {
      collectionByHandle(handle: "homepage") {
        id
        title
        products(first: 12) {
          edges {
            node {
              id
              title
              variants(first: 1) {
                edges {
                  node {
                    id
                  }
                }
              }
              images(first: 1) {
                edges {
                  node {
                    altText
                    transformedSrc
                  }
                }
              }
            }
          }
        }
      }
    }
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;graphQLClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&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;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&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;Unable to retrieve Shopify Products. Please check logs&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="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;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;homepageData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;collection&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;collectionByHandle&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's walk through the changes we have made.&lt;/p&gt;

&lt;p&gt;First we are creating a new instance of the GraphQLClient class and assigning it to a variable called &lt;code&gt;graphQLClient&lt;/code&gt;. You will see that we are assigning a header to our request client called &lt;code&gt;X-Shopify-Storefront-Access-Token&lt;/code&gt;. This is a required header that Shopify uses to authenticate your request.&lt;/p&gt;

&lt;p&gt;In our query we are requesting the first twelve products from the Homepage collection. The &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;after&lt;/code&gt; params are used for &lt;a href="https://shopify.dev/concepts/graphql/pagination" rel="noopener noreferrer"&gt;pagination&lt;/a&gt;. These numbers can be adjusted accordingly, but twelve is the maximum number of products I want to show on the homepage. As part of our request for products we are also requesting the first product image and product variant.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;A quick note on variants&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are a number of mutations in the Storefront API that require the use of a product's variant ID. For example, &lt;a href="https://shopify.dev/docs/storefront-api/reference/checkouts/checkoutcreate" rel="noopener noreferrer"&gt;&lt;code&gt;checkoutCreate&lt;/code&gt;&lt;/a&gt;, is something we will look at later. For simplicity, the product cards we create will display the first available variant. There may be occasions where a vendor stocks products with a single variant. For example, a vendor who sells artwork. In this case, you still have to present a variant ID to these mutations. Shopify will give you a variant ID (even if the product does not have any variants). This is something that has confused me in the past, so I wanted to share this with you to avoid making the mistakes I made when learning these APIs!&lt;/p&gt;

&lt;p&gt;Now, using &lt;code&gt;graphql-request&lt;/code&gt; we can perform our request to the Storefront API and pass the response into the data object that will be passed to the page as a prop.&lt;/p&gt;

&lt;p&gt;If all is well, you will see that your page has rebuilt successfully. However, we still need to update the UI to use present the data from Shopify.&lt;/p&gt;

&lt;p&gt;Now let's make some changes to the homepage template.&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;// web/pages/index.js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HomePage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&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;homepageData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&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;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-50"&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-96 bg-indigo-500 flex justify-center items-center"&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;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-white font-semibold text-6xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;homepageData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heroTitle&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;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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"container mx-auto py-12"&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;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-semibold text-4xl mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Featured Products&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid grid-flow-row grid-cols-3 grid-rows-auto gap-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductCard&lt;/span&gt; &lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&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;})&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;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;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;You should see an error regarding the &lt;code&gt;&amp;lt;ProductCard&amp;gt;&lt;/code&gt; component. That's because we haven't created it yet so let's do that!&lt;/p&gt;

&lt;p&gt;Create a folder in the root of your project called &lt;code&gt;components/&lt;/code&gt;, then create a file called &lt;code&gt;ProductCard.jsx&lt;/code&gt; and place the following code within 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="c1"&gt;// web/components/ProductCard.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/router&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;gql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLClient&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;graphql-request&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&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/image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&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/link&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;function&lt;/span&gt; &lt;span class="nf"&gt;ProductCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;product&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;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-center bg-white rounded-xl p-8 shadow-md pt-6 md:p-8 space-y-8"&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
          &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transformedSrc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"125"&lt;/span&gt;
          &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"125"&lt;/span&gt;
          &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;altText&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rounded-full"&lt;/span&gt;
          &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cover"&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&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;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-semibold text-2xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-medium"&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;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-100 text-gray-800 px-6 py-2 rounded block"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            View Product
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&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;Link&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to import the &lt;code&gt;&amp;lt;ProductCard /&amp;gt;&lt;/code&gt; component into &lt;code&gt;/pages/index.js&lt;/code&gt;. With this imported, you should now see that the collection section contains products from your Shopify instance!&lt;/p&gt;

&lt;h2&gt;
  
  
  How will users navigate to the checkout?
&lt;/h2&gt;

&lt;p&gt;To wrap things up, we're going to make some changes to our product card. We're going to introduce a function that will generate a Shopify checkout via the API. To accomplish this, we'll use a Storefront &lt;a href="https://graphql.org/learn/queries/#mutations" rel="noopener noreferrer"&gt;GraphQL Mutation&lt;/a&gt; called checkoutCreate.&lt;/p&gt;

&lt;p&gt;First, let's add a button above the "View Product" link:&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;// web/components/ProductCard.jsx&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-medium"&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;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="nf"&gt;createCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`bg-indigo-500 text-white px-6 py-2 rounded block mb-4 w-full &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
      &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;opacity-70 cursor-not-allowed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please Wait...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Buy Now&lt;/span&gt;&lt;span class="dl"&gt;"&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;button&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;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-100 text-gray-800 px-6 py-2 rounded block"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      View Product
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&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;Link&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we're going to write our function that will call the storefront mutation. Insert the following function within your &lt;code&gt;ProductCard.jsx&lt;/code&gt; 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="c1"&gt;// web/components/ProductCard.jsx&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Create Checkout Function
 * Creates a shopify checkout url and redirects customer
 * to the Shopify checkout page.
 * @param {string} variantId
 */&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;createCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variantId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;graphQLClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GraphQLClient&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;NEXT_PUBLIC_SHOPIFY_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Shopify-Storefront-Access-Token&lt;/span&gt;&lt;span class="dl"&gt;"&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;NEXT_PUBLIC_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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mutation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
    mutation checkoutCreate($input: CheckoutCreateInput!) {
      checkoutCreate(input: $input) {
        checkout {
          id
          webUrl
        }
        checkoutUserErrors {
          code
          field
          message
        }
      }
    }
  `&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;variables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;lineItems&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="nx"&gt;variantId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;quantity&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="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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;graphQLClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variables&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkoutCreate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkoutUserErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There was a problem processing the request.&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkoutCreate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webUrl&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;The function we have created is posting a &lt;a href="https://graphql.org/learn/queries/#mutations" rel="noopener noreferrer"&gt;GraphQL Mutation&lt;/a&gt; to the Storefront API. The mutation we are using is called &lt;code&gt;checkoutCreate&lt;/code&gt;. If you take a closer look at the mutation string, you can see that we are defining a variable called &lt;code&gt;$input&lt;/code&gt;:&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;// web/components/ProductCard.jsx&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mutation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  mutation checkoutCreate($input: CheckoutCreateInput!) {
    checkoutCreate(input: $input) {
      checkout {
        id
        webUrl
      }
      ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the GraphQL Request package we can pass variables through to the request as an object. You will notice that we have created a variable called variables which contains the input object that Shopify needs in order to generate the checkout.&lt;/p&gt;

&lt;p&gt;Finally, we specify that the mutation returns a property called &lt;code&gt;webUrl&lt;/code&gt;. This is the checkout URL that we can redirect customers to in order to purchase a product.&lt;/p&gt;

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

&lt;p&gt;Well done! Now you have a headless cms/commerce solution that you can build on or use as a foundation for future projects. There are various ways that you can build on this, why not try some of these extras?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create product landing pages with Next dynamic routes and the Shopify API.&lt;/li&gt;
&lt;li&gt;Use React context to create a basket that customers can add products to. Then, using the basket data, you can create a  with the from the basket.&lt;/li&gt;
&lt;li&gt;Consider ways you can make use of Sanity for powerful marketing material on your site such as carousels, feature sections or landing pages.&lt;/li&gt;
&lt;li&gt;Perhaps you can try upselling products as part of the blog on your website. &lt;a href="https://github.com/JamieBradders/sanity-shopify-lookup" rel="noopener noreferrer"&gt;I created a Sanity plugin&lt;/a&gt; to help with scenarios such as this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for taking the opportunity to read through this tutorial. If you have any questions then please feel free to find me on Twitter (I use the handle @jamiebradley234) or amongst the Sanity Slack!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>shopify</category>
      <category>sanity</category>
      <category>jamstack</category>
    </item>
    <item>
      <title>React Splide with Gatsby: Top Tip</title>
      <dc:creator>Jamie Bradley</dc:creator>
      <pubDate>Thu, 07 Jan 2021 18:40:29 +0000</pubDate>
      <link>https://forem.com/jamiebradley/react-splide-with-gatsby-top-tip-1ppe</link>
      <guid>https://forem.com/jamiebradley/react-splide-with-gatsby-top-tip-1ppe</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update: Splide is now in Version 3 and (since the update) &lt;a href="https://github.com/Splidejs/react-splide" rel="noopener noreferrer"&gt;React Splide&lt;/a&gt; appears to work well with Gatsby (tested on V4) without any additional configuration. This article is only useful to those using an older version of React Splide&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;If you have never come across SplideJS then I encourage you to check it out. It's a great plugin for building carousels and I think the documentation is brilliant. &lt;a href="http://splidejs.com/" rel="noopener noreferrer"&gt;Check out SplideJS here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let me start by telling you about my painful afternoon...&lt;/p&gt;

&lt;p&gt;Today, I have been working on a website for a client using Gatsby. Until today, everything has been going great! My task today was to develop a carousel component, so I turned to my favourite tool (Splide) and I noticed they have a React port. "Awesome" I thought, "This is going to be simple!".&lt;/p&gt;

&lt;p&gt;Then I noticed an error in the Netlify logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  14 |  else
  15 |      root["Splide"] = factory();
&amp;gt; 16 | })(self, function() {
     |  ^
  17 | return /******/ (() =&amp;gt; { // webpackBootstrap
  18 | /******/     "use strict";
  19 | /******/     var __webpack_modules__ = ({


  WebpackError: ReferenceError: self is not defined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This doesn't look good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Gatsby HTML Builds
&lt;/h2&gt;

&lt;p&gt;There's a great section in the Gatsby documentation about debugging HTML builds &lt;a href="https://www.gatsbyjs.com/docs/debugging-html-builds/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I consulted this and found the section on third-party modules. I have used this approach with other packages that expect the &lt;code&gt;window&lt;/code&gt; object during the HTML build, so I thought I would give this a go.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;gatsby-node.js&lt;/code&gt; I added the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onCreateWebpackConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loaders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actions&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="c1"&gt;// With SSR enabled during development, we capture this&lt;/span&gt;
  &lt;span class="c1"&gt;// in development and during production build.&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;stage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build-html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;stage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;develop-html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setWebpackConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;rules&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;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/@splidejs/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;loaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;null&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="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;Great 💥 let's run &lt;code&gt;gatsby build&lt;/code&gt; again...oh dear&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Minified React error #130; visit https://reactjs.org/docs/error-decoder.html?invariant=130&amp;amp;args[]=undefined&amp;amp;args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a new error. A new error is good, it means progress! If we copy the error decoder URL into a new browser we can see that React returned the following error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first I was puzzled, but after a coffee it made sense. We have told webpack to replace React Splide with a dummy module. The &lt;code&gt;loaders.null()&lt;/code&gt; suggests that we're not going to return anything valuable - it's &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So the end result for my carousel component was this:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Testimonials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;undefined&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="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;Server Render&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;}&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;&lt;/span&gt;&lt;span class="nc"&gt;Box&lt;/span&gt; &lt;span class="na"&gt;mb&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&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;Splide&lt;/span&gt;
        &lt;span class="na"&gt;options&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="na"&gt;perPage&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="na"&gt;perMove&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="na"&gt;arrows&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="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;testimonial&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SplideSlide&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;testimonial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;Flex&lt;/span&gt; &lt;span class="na"&gt;bgColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"blue.600"&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;Box&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"400px"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* To be replaced with Gatsby Image */&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;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;testimonial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;testimonial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alt&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;Box&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;Box&lt;/span&gt; &lt;span class="na"&gt;py&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;px&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex"&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"white"&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;PortableText&lt;/span&gt; &lt;span class="na"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;testimonial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_rawTestimonialText&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;Box&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;Flex&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;SplideSlide&lt;/span&gt;&lt;span class="p"&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="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Splide&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;Box&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that when the HTML build takes place, the component will return &lt;code&gt;&amp;lt;p&amp;gt;Server Render&amp;lt;/p&amp;gt;&lt;/code&gt; rather than &lt;code&gt;undefined&lt;/code&gt;. If we run the code in the browser, &lt;code&gt;window&lt;/code&gt; is defined and we will see the Splide component.&lt;/p&gt;

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

&lt;p&gt;I wrote this with the hope that it will help anyone else who comes across this problem. If you found it useful then let me know in the comments.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Managing Diabetes with the Jamstack: The Idea 💡</title>
      <dc:creator>Jamie Bradley</dc:creator>
      <pubDate>Fri, 31 Jan 2020 17:05:45 +0000</pubDate>
      <link>https://forem.com/jamiebradley/managing-diabetes-with-jamstack-the-idea-2gi3</link>
      <guid>https://forem.com/jamiebradley/managing-diabetes-with-jamstack-the-idea-2gi3</guid>
      <description>&lt;p&gt;On the 23rd December 2003, at the age of 14, I became ill and ended up in hospital. I was very quickly diagnosed with Type 1 Diabetes. 2019 marked my 17th year with Diabetes and as I write this post I find myself reflecting over the years and realising how much technology has positively impacted people who suffer with Diabetes.&lt;/p&gt;

&lt;p&gt;However, despite these revolutions there's still a problem...&lt;/p&gt;

&lt;p&gt;But before we discuss the problem and look at how I want to help solve this problem let's take a quick biology lesson.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Diabetes?
&lt;/h2&gt;

&lt;p&gt;According to the &lt;a href="https://www.nhs.uk/conditions/diabetes/" rel="noopener noreferrer"&gt;NHS Website&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Diabetes is a lifelong condition that causes a person's blood sugar level to become too high.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you think back to Science lessons at school you will have learned about an organ called the &lt;strong&gt;Pancreas&lt;/strong&gt;. The Pancreas is responsible for the generation of an enzyme called &lt;strong&gt;Insulin&lt;/strong&gt;. Insulin is a hormone that our bodies use to breakdown sugars (a byproduct of Carbohydrates that we eat) in our bloodstream. &lt;/p&gt;

&lt;p&gt;So when a person with a healthy pancreas eats a meal their body will release the exact amount of insulin needed to break down the sugars consumed in that meal. Those who suffer with Diabetes are either unable to produce the right amount of insulin (Type 2) or unable to produce any insulin at all (Type 1).&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between the two groups?
&lt;/h3&gt;

&lt;p&gt;The main differences are the root causes and treatment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;type 1 diabetes – caused when the body's immune system attacks and destroys the cells that produce insulin. Type 1 diabetes is &lt;strong&gt;not reversible&lt;/strong&gt;. Type 1 diabetes is treated by injecting insulin, with pen injections or an insulin pump, to replicate the pancreas' behaviour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;type 2 diabetes – caused when the body does not produce enough insulin, or the body's cells do not react to insulin. The exact reason for this is unknown but obesity, being inactive and genetics are often factors that are associated with this type. Type 2 diabetes is often treated by making lifestyle changes and the prescription of tablets. Type 2 diabetes is potentially reversible if diagnosed early enough and drastic lifestyle changes are made.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How is Type 1 Diabetes Managed?
&lt;/h3&gt;

&lt;p&gt;Type 1 Diabetics manage the disease by carrying out several blood sugar tests every day, usually before a meal. Ths involves using a blood sugar monitor which returns a blood sugar count. Using this reading and a carbohydrate count from our meals, we have to calculate the amount of insulin we need to take.&lt;/p&gt;

&lt;p&gt;We're only human so we're bound to get insulin amounts wrong. If we don't take enough insulin our blood sugar count rises and this is called &lt;strong&gt;Hyperglycemia&lt;/strong&gt;. If we take too much insulin our blood sugar count drops and this is called &lt;strong&gt;Hypoglycemia&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I have no idea how Type 2 Diabetes is managed on a daily basis. If someone lives with Type 2 Diabetes and would like to make a contribution to this article then I'm all ears!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Which is Worse?
&lt;/h3&gt;

&lt;p&gt;A common question I get asked by friends, co-workers etc is "Which is worse? Type 1 or type 2?". In my opinion, both can be as bad as each other. In the UK type 2 diabetes is a lot more common that type 1. The NHS website states that "around 90% of all adults with diabetes have type 2". But, regardless of the type, if diabetes is poorly managed and blood sugar levels aren't stable then complications can arise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Problems with eyes, potentially resulting in loss of eye sight&lt;/li&gt;
&lt;li&gt;Problems with legs and feet, potentially resulting in ampuation&lt;/li&gt;
&lt;li&gt;High Cholesterol&lt;/li&gt;
&lt;li&gt;High Blood Pressure&lt;/li&gt;
&lt;li&gt;Cardiovascular Disease&lt;/li&gt;
&lt;li&gt;Kidney Failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the UK these complications add serious stress to our National Health Service. Managing diabetes effectively can drastically reduce these potential complications. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Phew! 😅&lt;/p&gt;

&lt;p&gt;Hopefully I haven't bored you away from the article. If you're still with me then let's talk about the problem with technology in diabetes.&lt;/p&gt;

&lt;p&gt;Technology is expensive and it isn't accessible to everyone who suffers with diabetes. As a Brit I am very thankful for the NHS. I treat my Diabetes with an Insulin Pump combined with a CGM (Continous Glucose Monitor) - both of which are funded by the NHS. With this technology I am able to look over previous readings on a graph and adjust medication levels accordingly. &lt;/p&gt;

&lt;p&gt;However, there isn't enough funding for every diabetic to access this treatment. We also have to remember that not every country has a service like the NHS which means diabetics outside of the UK have to fund their own treatment. Those who don't use insulin pumps or CGM's are relying on the functionality of their blood glucose monitor, most of which are very good at reading blood sugars but not painting the bigger picture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Got an Insulin Pump/CGM?
&lt;/h3&gt;

&lt;p&gt;If you do have access to this technology then you should checkout the &lt;a href="http://www.nightscout.info/" rel="noopener noreferrer"&gt;Nightscout Project&lt;/a&gt;. Nightscout is an Open Source, DIY project that helps you get your CGM data into the cloud. This allows for remote monitoring of blood sugars - great for parents!&lt;/p&gt;

&lt;p&gt;There's an awesome talk by &lt;a href="https://twitter.com/shanselman" rel="noopener noreferrer"&gt;Scott Hanselman&lt;/a&gt; that was recorded in 2015. In this talk Scott showcases the Night Scout software and discusses CGM data in the cloud. &lt;a href="https://www.youtube.com/watch?v=TSBZIoLWJQo" rel="noopener noreferrer"&gt;Check out the video here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Solution
&lt;/h2&gt;

&lt;p&gt;Don't get me wrong. Nightscout is an awesome project but it seems very much geared towards diabetics with a CGM and an Insulin Pump. There's also an essence of hacking involved to make the hardware work with the software - this isn't ideal for those who receive pumps through the NHS (it'll void the warranty).&lt;/p&gt;

&lt;p&gt;So what about those who are still taking injections for their insulin? Or those who use pumps that have been prescribed by the NHS? How can we provide these users with a similar experience?&lt;/p&gt;

&lt;p&gt;I want to create a system that is easy to deploy, cheap to host, secure and fast. This is where &lt;a href="https://jamstack.org/" rel="noopener noreferrer"&gt;JAMstack&lt;/a&gt; comes in!&lt;/p&gt;

&lt;h3&gt;
  
  
  Why JAMstack?
&lt;/h3&gt;

&lt;p&gt;We've been doing a lot of work with JAMstack at &lt;a href="https://endeavour.digital" rel="noopener noreferrer"&gt;Endeavour Digital&lt;/a&gt; and the more I work with it, the more potential I see with this architecture. More importantly there are services in this space that I can utilise to meet my criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Netlify&lt;/strong&gt; - An easy to use and affordable hosting solution for static websites and client side applications. The free tier comes with an environment for executing lambda functions which is perfect for what I have in mind. As for keeping deployments simple, their &lt;a href="https://www.netlify.com/blog/2016/11/29/introducing-the-deploy-to-netlify-button/" rel="noopener noreferrer"&gt;'deploy to Netlify' button&lt;/a&gt; will be super useful here!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;Update 18.05.2020 *&lt;/em&gt; - Since posting this article I made the decision to store blood results on the &lt;a href="https://sanity.io" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; platform, as oppose to &lt;a href="https://fauna.com/" rel="noopener noreferrer"&gt;Fauna&lt;/a&gt;. I wanted to get something online quickly and started to get distracted from my primary goal as I started developing the custom admin interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sanity provides a fantastic interface out of the box, that similar to a CMS, and it is very flexible. This means I can move my focus to the presentation layer whilst still delivering a great data entry experience for my users.&lt;/p&gt;

&lt;p&gt;However, this isn't the end of my journey with Fauna. There are other ideas that I want to explore which will work perfectly with the Fauna Platform. So, &lt;a href="https://fauna.com/" rel="noopener noreferrer"&gt;please check them out&lt;/a&gt;, it's really awesome, and stay posted for my other Jamstack ideas!!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gatsby&lt;/strong&gt; - I'll be using Gatsby to develop the UI. I love Gatsby and I find it's &lt;a href="https://www.gatsbyjs.org/docs/adding-app-and-website-functionality/#hybrid-app-pages" rel="noopener noreferrer"&gt;Hybrid Pages feature&lt;/a&gt; both useful and awesome.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Boring Solution
&lt;/h3&gt;

&lt;p&gt;My good friend &lt;a href="https://twitter.com/samdbeckham" rel="noopener noreferrer"&gt;Sam Beckham&lt;/a&gt; introduced me to the idea of starting with the "Boring Solution". In other words the minimum functionality required to get a job done. Naturally I have A LOT of ideas for this application but I need to prove the concept first.&lt;/p&gt;

&lt;p&gt;So I'll start with the boring solution, this will let me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Publish data to FaunaDB via the Fauna dashboard. That's right, I'll not be bothering with a custom interface at this stage and why bother if there's one there for me to use?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trigger a &lt;code&gt;gatsby build&lt;/code&gt; on Netlify when data is updated. I'm going to try and keep my site as static as possible and this includes pre-fetching Fauna data. Since data is inputted manually and via my CGM I don't need a real-time interface, nor will I be triggering hundreds of deploys each day.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Display results in a graph on a basic front end built with Gatsby.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Less Boring Solution
&lt;/h3&gt;

&lt;p&gt;If I find my proof of concept useful then I will continue to build on this idea. I already have some things in mind that I would like to try which include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Integrating a Netlify Function with iOS Shortcuts/IFTTT! This means I'll be able to publish results from my phone easily.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Develop an authenticated application for posting data to Fauna. So I can publish data via a web application rather than the Fauna dashboard. It'll also make posting data easier for less technical users (I would like to Open Source something if this works out).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;I'm sure more and more ideas will come up as I work through this. But I'm really excited to see how far I can go with JAMstack and learn more about what these services are capable of.&lt;/p&gt;

&lt;p&gt;I intend to keep writing about my progress and hope that I can finish with something that I can showcase and talk about at meetups and conferences. &lt;/p&gt;

&lt;p&gt;If you also suffer with diabetes and have some ideas you would like to share or would just like to chat to a fellow human with a silly pancreas, then please feel free to reach out to me on Twitter &lt;a href="https://twitter.com/jamiebradley234" rel="noopener noreferrer"&gt;@jamiebradley234&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>react</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
