<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bolaji Ayodeji</title>
    <description>The latest articles on DEV Community by Bolaji Ayodeji (@bolajiayodeji).</description>
    <link>https://dev.to/bolajiayodeji</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%2F110214%2Fba08b523-eeec-4dfe-ac61-5fa605c2df76.png</url>
      <title>DEV Community: Bolaji Ayodeji</title>
      <link>https://dev.to/bolajiayodeji</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bolajiayodeji"/>
    <language>en</language>
    <item>
      <title>Creating an Automated Profile README using Nodejs and GitHub Actions</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Mon, 26 Feb 2024 14:35:05 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/how-to-create-an-automated-profile-readme-using-nodejs-and-github-actions-1d30</link>
      <guid>https://dev.to/bolajiayodeji/how-to-create-an-automated-profile-readme-using-nodejs-and-github-actions-1d30</guid>
      <description>&lt;p&gt;Some years ago, GitHub introduced the new Profile README feature that allowed GitHub users to pin a markdown file on their profile using a special repository named after their GitHub username. Since then, developers have used this file as a quick portfolio and for highlighting their achievements. I wrote &lt;a href="https://blog.bolajiayodeji.com/how-to-add-a-readme-file-to-your-github-profile" rel="noopener noreferrer"&gt;an article&lt;/a&gt; shortly after the release to share how to set it up and highlight some cool profiles I had seen. This tutorial is a sequel to that article, and I will share how I took my GitHub profile to the next level with the power of scripting and CI/CD automation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701643614721%2Feb0Mwocec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701643614721%2Feb0Mwocec.png" alt="Screenshot of my GitHub README Profile page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, you'll learn how to automate your GitHub README Profile so that it can update itself anytime you want. We will make this possible using a custom script built with Nodejs/TypeScript, markdown-it library, GitHub API, RSS feeds, and GitHub Actions. If you want to see the code, you can &lt;a href="https://github.com/BolajiAyodeji/BolajiAyodeji" rel="noopener noreferrer"&gt;head to this repository&lt;/a&gt;, but you should read along to learn one or two things you can apply in other use cases (especially if you're new to writing automated scripts).&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To get the best out of this tutorial, you need to know/do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Have an existing GitHub account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read the &lt;a href="https://blog.bolajiayodeji.com/how-to-add-a-readme-file-to-your-github-profile" rel="noopener noreferrer"&gt;first article&lt;/a&gt; and create your README profile.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have Nodejs and NPM installed on your computer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some prior knowledge of the JavaScript programming language.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;GitHub allows you to pin only six (6) repositories on your profile. I wanted to highlight more repositories while retaining the existing ones in the most minimal way possible (without having to use &lt;a href="https://github.com/anuraghazra/github-readme-stats#github-extra-pins" rel="noopener noreferrer"&gt;these kinds of badges&lt;/a&gt;). I also wanted a way to highlight some content from &lt;a href="https://bawd.bolajiayodeji.com" rel="noopener noreferrer"&gt;my newsletter&lt;/a&gt; so I can get some traffic from there and potentially new subscribers that fit my target audience. I remember seeing some profiles in the past that listed their latest blog posts or music they were listening to. So I researched, found some of those profiles, and discovered they ran a script that automatically generated their markdown file. I then decided to make mine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Proposed Solution
&lt;/h2&gt;

&lt;p&gt;Generally, the README file is written in &lt;a href="https://markdownguide.org/getting-started?utm_source=https://blog.bolajiayodeji.com" rel="noopener noreferrer"&gt;markdown&lt;/a&gt;, a markup language for creating formatted text. The goal is to simultaneously generate the entire markdown file, including the static and dynamic sections. This includes the badges, open-source statistics, and text descriptions. The new dynamic sections are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;List of selected GitHub repositories.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List of my recent blog posts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List of my recent newsletters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;We can easily use &lt;a href="https://github.com/markdown-it/markdown-it" rel="noopener noreferrer"&gt;markdown-it&lt;/a&gt;, a markdown parser for rendering a mix of JavaScript and plain text into a markdown file. To get started, kindly create a new directory with the following file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌── .github
    ┌──  workflows
        ├── build.yml
┌── src
    ├── app.ts
    ├── fetchGitHubData.ts
    ├── fetchRssData.ts
├── package.json
└── tsconfig.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install the required &lt;a href="https://github.com/BolajiAyodeji/BolajiAyodeji/blob/main/package.json" rel="noopener noreferrer"&gt;packages&lt;/a&gt; using the command below:&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;fs markdown-it rss-parser tsc-watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;--save-dev&lt;/span&gt; @types/node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm using TypeScript and will use &lt;code&gt;ts&lt;/code&gt; to compile to JavaScript during the build. My &lt;code&gt;tsconfig.json&lt;/code&gt; and &lt;code&gt;package.json&lt;/code&gt; scripts file looks looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;tsconfig.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES2015"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"skipLibCheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bolajiayodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bolaji Ayodeji's GitHub Profile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/app.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx tsc-watch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build &amp;amp;&amp;amp; node build/app.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetching the Data from GitHub API
&lt;/h2&gt;

&lt;p&gt;You can fetch different kinds of data with &lt;a href="https://docs.github.com/en/rest" rel="noopener noreferrer"&gt;GitHub's API&lt;/a&gt;. There are two options: use &lt;a href="https://api.github.com" rel="noopener noreferrer"&gt;the API&lt;/a&gt; directly or the &lt;a href="https://github.com/octokit/octokit.js" rel="noopener noreferrer"&gt;Octokit.js library&lt;/a&gt; (this is the route GitHub recommends). I decided to use the API directly since the Octokit.js library included extra stuff I wouldn't need, which is an overkill for this use case.&lt;/p&gt;

&lt;p&gt;To fetch a repository, you will use the &lt;code&gt;https://api.github.com/repos/{owner}/{name}&lt;/code&gt; endpoint with some parameters. &lt;code&gt;owner&lt;/code&gt; represents my GitHub username and &lt;code&gt;name&lt;/code&gt; is the repository's name. A GET request should return a JSON data like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;278287314&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"node_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MDEwOlJlcG9zaXRvcnkyNzgyODczMTQ="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BolajiAyodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"full_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BolajiAyodeji/BolajiAyodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"login"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BolajiAyodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30334776&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"node_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MDQ6VXNlcjMwMzM0Nzc2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"avatar_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://avatars.githubusercontent.com/u/30334776?v=4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"gravatar_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.github.com/users/BolajiAyodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"html_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/BolajiAyodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"html_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/BolajiAyodeji/BolajiAyodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My automated GitHub Profile README built using TypeScript and GitHub Actions."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-07-09T06:55:36Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2023-11-11T09:25:16Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"stargazers_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"watchers_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TypeScript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"open_issues_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT License"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"topics"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"github-actions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"github-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"hashnode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"javascript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"visibility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"forks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test this live yourself: &lt;a href="https://api.github.com/repos/BolajiAyodeji/BolajiAyodeji" rel="noopener noreferrer"&gt;&lt;code&gt;api.github.com/repos/BolajiAyodeji/BolajiAyodeji&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you make a request to GitHub's API using an access token through the Octokit.js library, you can make API requests without passing the &lt;code&gt;owner&lt;/code&gt; parameter. GitHub will infer that from your token.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we will create a &lt;code&gt;fetchGitHubData()&lt;/code&gt; function in &lt;code&gt;src/fetchGitHubData.ts&lt;/code&gt; that will accept an array of repository names as the parameter. This array will look like this:&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="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BolajiAyodeji&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;fed-unis-perf-eval&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;movie_reviews_sentiment_analysis&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;dotfiles&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;Here's the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchGitHubData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BolajiAyodeji&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;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;repos&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="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://api.github.com/repos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`"&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" not found. Kindy review your list of repositories.`&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;data&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;html_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;stargazers_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;forks_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;forks&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="nx"&gt;desc&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="s2"&gt;`&amp;lt;li&amp;gt;&amp;lt;a href=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; target="_blank" rel="noopener noreferrer"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt; (&amp;lt;b&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/b&amp;gt; ✨ and &amp;lt;b&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;forks&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/b&amp;gt; 🍴): &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n&amp;lt;li&amp;gt;More coming soon :).&amp;lt;/li&amp;gt;\n&amp;lt;/ul&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the function above, we loop through the array, fetch data for all the repositories, and extract the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;html_url&lt;/code&gt;: link to the repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;full_name&lt;/code&gt;: name of the repository (including my username attached)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;stargazers_count&lt;/code&gt;: number of stars.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;forks_count&lt;/code&gt;: number of forks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;description&lt;/code&gt;: description of the repository.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We then use the data to render an HTML list element (&lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;) for each repository in the array, join all the lists together, add an additional static list element with custom text, and return an unordered HTML list element (&lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;). The final result should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701722479958%2FLwGreLLVS.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701722479958%2FLwGreLLVS.png" alt="Screenshot of my GitHub README Profile page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function is useless for now, but we will use it later in &lt;code&gt;src/app.ts&lt;/code&gt; to render the markdown. Let's proceed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching the Data from RSS Feeds
&lt;/h2&gt;

&lt;p&gt;We can use an RSS feed for the blog post and newsletter sections. According to &lt;a href="https://en.wikipedia.org/wiki/RSS?utm_source=https://blog.bolajiayodeji.com" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;, RSS (Really Simple Syndication) is a web feed written in XML (eXtensible Markup Language) that allows users and applications to access website updates in a computer-readable format. People use RSS to access the latest published content from a website page. Mostly, a user will use an RSS reader to access content from multiple XML files in an organized manner and read them.&lt;/p&gt;

&lt;p&gt;My blog runs on Hashnode, which provides an &lt;code&gt;rss.xml&lt;/code&gt; file by default on &lt;code&gt;https://blog.bolajiayodeji.com/rss.xml&lt;/code&gt;. My newsletter also runs on Substack, which also provides an &lt;code&gt;rss.xml&lt;/code&gt; file on &lt;code&gt;https://bawd.bolajiayodeji.com/feed&lt;/code&gt;. So, each time a new post is added to my blog or newsletter, the RSS feed automatically includes the page's current data. This makes it a good data source for my GitHub Profile.&lt;/p&gt;

&lt;p&gt;Since both RSS feeds are similar in structure, I can create a &lt;code&gt;fetchRssData()&lt;/code&gt; function in &lt;code&gt;src/fetchRssData.ts&lt;/code&gt; for both. We will first use the &lt;a href="https://github.com/rbren/rss-parser" rel="noopener noreferrer"&gt;rss-parser&lt;/a&gt; library to turn the RSS XML feeds into JavaScript objects and then iterate to find the necessary fields.&lt;/p&gt;

&lt;p&gt;The XML looks like this (&lt;a href="https://blog.bolajiayodeji.com/rss.xml" rel="noopener noreferrer"&gt;view the image below live for a better experience&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701638268459%2FnWfEscD3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701638268459%2FnWfEscD3g.png" alt="Screenshot of the RSS feed of my blog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The parsed version looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"creator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bolaji Ayodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Developer Advocate Portfolio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://blog.bolajiayodeji.com/my-developer-advocate-portfolio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pubDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mon, 28 Aug 2023 13:03:08 GMT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dc:creator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bolaji Ayodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"contentSnippet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"guid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://blog.bolajiayodeji.com/my-developer-advocate-portfolio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"isoDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2023-08-28T13:03:08.000Z"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;another&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;item...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;items...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"creator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bolaji Ayodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"How to Deploy a Machine Learning Model to the Web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://blog.bolajiayodeji.com/how-to-deploy-a-machine-learning-model-to-the-web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pubDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sat, 03 Sep 2022 08:49:08 GMT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dc:creator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bolaji Ayodeji"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what the final function will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Parser&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;rss-parser&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;parser&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;Parser&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;fetchRssData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;feed&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;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&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="mi"&gt;5&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;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&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;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pubDate&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publishedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;li&amp;gt;&amp;lt;a href=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; target="_blank" rel="noopener noreferrer"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;publishedDate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;).&amp;lt;/li&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`
  &amp;lt;ul&amp;gt;
    &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;
  &amp;lt;/ul&amp;gt;\n
  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rss.xml&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="s2"&gt;`Read more blog posts: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;rss.xml$/&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Read more newsletter issues: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;feed$/&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the function above, we use the RSS link to fetch the data, extract just the first five items (posts), and extract the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pubDate&lt;/code&gt;: timestamp for when the content was published.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;link&lt;/code&gt;: link to the post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;title&lt;/code&gt;: title of the post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We then use the data to render an HTML list element (&lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;) for each published post, do some date formatting, join all the lists together, add an additional static list element with custom text, and return an unordered HTML list element (&lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;). The final result should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701723020483%2FKzTrsaasQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701723020483%2FKzTrsaasQ.png" alt="Screenshot of my GitHub README Profile page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating the Final Markdown File
&lt;/h2&gt;

&lt;p&gt;Now that we have the &lt;code&gt;fetchGitHubData()&lt;/code&gt; and &lt;code&gt;fetchRssData()&lt;/code&gt; functions, let's combine everything and generate the &lt;code&gt;README.md&lt;/code&gt; file we need. In &lt;code&gt;src/app.ts&lt;/code&gt; add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;fs&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;fs&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;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdown-it&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;html&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="c1"&gt;// Enable HTML tags in source&lt;/span&gt;
  &lt;span class="na"&gt;breaks&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="c1"&gt;// Convert '\n' in paragraphs into &amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;linkify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// Autoconvert URL-like text to links&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;fetchRssData&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;./fetchRssData&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;fetchGitHubData&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;./fetchGitHubData&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;blogFeedUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://blog.bolajiayodeji.com/rss.xml&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;newsletterFeedUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://bawd.bolajiayodeji.com/feed&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;ossProjectRepos&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;BolajiAyodeji&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;fed-unis-perf-eval&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;movie_reviews_sentiment_analysis&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;dotfiles&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;ossLearningMaterialRepos&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;deploy-ml-web-workshop&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;cl-composable-commerce-workshop&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;githubUsername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BolajiAyodeji&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;websiteUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://bolajiayodeji.com&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;blogUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://blog.bolajiayodeji.com&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;newsletterUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://bawd.bolajiayodeji.com&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;youtubeUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://youtube.com/c/bolajiayodeji&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;slidesUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://slides.com/bolajiayodeji&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;twitterUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://twitter.com/iambolajiayo&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;linkedinUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://linkedin.com/in/iambolajiayo&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;githubSponsorsUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://github.com/sponsors/BolajiAyodeji&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;patreonUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://patreon.com/bolajiayodeji&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&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;generateMarkdown&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;websiteBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![Website Badge](https://img.shields.io/badge/-Website-3B7EBF?style=for-the-badge&amp;amp;logo=amp&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;websiteUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;hashnodeBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![Blog Badge](https://img.shields.io/badge/-Blog-3B7EBF?style=for-the-badge&amp;amp;logo=Hashnode&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;blogUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;substackBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![Newsletter Badge](https://img.shields.io/badge/-Newsletter-3B7EBF?style=for-the-badge&amp;amp;logo=Substack&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;newsletterUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;youtubeBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![YouTube Badge](https://img.shields.io/badge/-Youtube-3B7EBF?style=for-the-badge&amp;amp;logo=Youtube&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;youtubeUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;slidesBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![Slides Badge](https://img.shields.io/badge/-Slides-3B7EBF?style=for-the-badge&amp;amp;logo=slides&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slidesUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;linkedinBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![Linkedin Badge](https://img.shields.io/badge/-LinkedIn-3B7EBF?style=for-the-badge&amp;amp;logo=Linkedin&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;linkedinUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;twitterBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![Twitter Badge](https://img.shields.io/badge/-@iambolajiayo-3B7EBF?style=for-the-badge&amp;amp;logo=x&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;twitterUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;githubSponsorsBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![GitHub Sponsors Badge](https://img.shields.io/badge/-github%20sponsors-3B7EBF?style=for-the-badge&amp;amp;logo=github&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubSponsorsUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;patreonBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![Patreon Badge](https://img.shields.io/badge/-Patreon-3B7EBF?style=for-the-badge&amp;amp;logo=Patreon&amp;amp;logoColor=white)](&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;patreonUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;profileCountBadge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`![Profile Views Count Badge](https://komarev.com/ghpvc/?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubUsername&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;style=for-the-badge)`&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;githubStatsCardDark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![GitHub-Stats-Card-Dark](https://github-readme-stats.vercel.app/api?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubUsername&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;show_icons=true&amp;amp;hide_border=true&amp;amp;include_all_commits=true&amp;amp;card_width=600&amp;amp;custom_title=GitHub%20Open%20Source%20Stats&amp;amp;title_color=3B7EBF&amp;amp;text_color=FFF&amp;amp;icon_color=3B7EBF&amp;amp;hide=contribs&amp;amp;show=reviews,prs_merged,prs_merged_percentage&amp;amp;theme=transparent#gh-dark-mode-only)](https://github.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubUsername&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubUsername&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;#gh-dark-mode-only)`&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;githubStatsCardLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[![GitHub-Stats-Card-Light](https://github-readme-stats.vercel.app/api?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubUsername&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;show_icons=true&amp;amp;hide_border=true&amp;amp;include_all_commits=true&amp;amp;card_width=600&amp;amp;custom_title=GitHub%20Open%20Source%20Stats&amp;amp;title_color=3B7EBF&amp;amp;text_color=474A4E&amp;amp;icon_color=3B7EBF&amp;amp;hide=contribs&amp;amp;show=reviews,prs_merged,prs_merged_percentage&amp;amp;theme=transparent#gh-light-mode-only)](https://github.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubUsername&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubUsername&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;#gh-light-mode-only)`&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;markdownText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div align="center"&amp;gt;\n

  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;websiteBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hashnodeBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;substackBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;youtubeBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slidesBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;linkedinBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;twitterBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubSponsorsBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;patreonBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;profileCountBadge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n

  ---\n

  Hi there 👋🏾! I'm an innovative technology professional with progressive IT, web engineering, data, embedded systems, developer relations, documentation, technical writing, open-source, community building, and entrepreneurship experience in for-profit startups and non-profit technology and education organizations. I create technical content, build open-source projects and learning materials, speak/teach at developer meetups/conferences, and build several technical communities.\n

  ---\n

  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubStatsCardDark&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n
  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;githubStatsCardLight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n

  &amp;lt;/div&amp;gt;\n

  ---\n

  ## Highlights

  &amp;lt;details&amp;gt;\n
  &amp;lt;summary&amp;gt;OSS Projects&amp;lt;/summary&amp;gt;\n
  &amp;lt;br /&amp;gt;
  Here are some of my other projects you might want to check out that are not pinned:\n
  &amp;lt;br /&amp;gt;\n&amp;lt;br /&amp;gt;
  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchGitHubData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ossProjectRepos&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n
  &amp;lt;/details&amp;gt;\n

  &amp;lt;details&amp;gt;\n
  &amp;lt;summary&amp;gt;OSS Learning Materials&amp;lt;/summary&amp;gt;\n
  &amp;lt;br /&amp;gt;
  Here are some of my unique-styled workshop materials you can use to learn key concepts at your own pace:\n
  &amp;lt;br /&amp;gt;\n&amp;lt;br /&amp;gt;
  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchGitHubData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ossLearningMaterialRepos&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n
  &amp;lt;/details&amp;gt;\n

  &amp;lt;details&amp;gt;\n
  &amp;lt;summary&amp;gt;Recent Blogposts&amp;lt;/summary&amp;gt;\n
  &amp;lt;br /&amp;gt;
  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchRssData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blogFeedUrl&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n
  &amp;lt;/details&amp;gt;\n

  &amp;lt;details&amp;gt;\n
  &amp;lt;summary&amp;gt;Recent Newsletters&amp;lt;/summary&amp;gt;\n
  &amp;lt;br /&amp;gt;
  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchRssData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newsletterFeedUrl&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n
  &amp;lt;/details&amp;gt;\n

  &amp;lt;details&amp;gt;\n
  &amp;lt;summary&amp;gt;Quick Tips&amp;lt;/summary&amp;gt;\n\n
  - 💬 How to reach me: DM [@iambolajiayo](https://twitter.com/iambolajiayo) on X (Twitter).\n
  - 📬 Where to find me: Subscribe to my [newsletter](https://bawd.bolajiayodeji.com/subscribe) to hear from me bi-weekly or send a game request on [chess.com](https://chess.com/member/bolajiayodeji).\n
  - 📖 Book recommendations: [Knowing God by J. I. Packer](https://bit.ly/3EdCFUW) and [Atomic Habits by James Clear](https://bit.ly/45r1kBH).\n
  - 💙 Fun fact: I'm in a blissful relationship [with Jesus Christ](https://biblegateway.com/passage/?search=1+Corinthians+15%3A1-11&amp;amp;version=NKJV). Check [this](https://bit.ly/3KYYHij) out :).\n
  &amp;lt;/details&amp;gt;\n

  ---\n

  &amp;lt;a href="#"&amp;gt;Learn how this works.&amp;lt;/a&amp;gt; &amp;lt;a href="https://github.com/BolajiAyodeji/BolajiAyodeji/actions/workflows/build.yml"&amp;gt;&amp;lt;img src="https://github.com/BolajiAyodeji/BolajiAyodeji/actions/workflows/build.yml/badge.svg" align="right" alt="Rebuild README.md file"&amp;gt;&amp;lt;/a&amp;gt;\n

  &amp;lt;div align="center"&amp;gt;\n
   &amp;lt;a href="https://bolajiayodeji.com" target="_blank" rel="noopener noreferrer"&amp;gt;&amp;lt;img src="https://bolajiayodeji.com/favicon.png" width="30" /&amp;gt;&amp;lt;/a&amp;gt;\n
  &amp;lt;/div&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;md&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdownText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Something went wrong: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="s2"&gt;`✅ README.md file was succesfully generated.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;generateMarkdown&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, I manually add all the static markdown content that existed before (text, badges, etc.) in the &lt;code&gt;markdownText&lt;/code&gt; variable, add the new dynamic sections with the functions, render the markdown file in the &lt;code&gt;result&lt;/code&gt; variable, and create the markdown file using Node.js's &lt;code&gt;fs.writeFile()&lt;/code&gt; method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the CI/CD Pipeline with GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Now, to the cool part! So far, the major work has been done, and if I run &lt;code&gt;npm run build&lt;/code&gt; and &lt;code&gt;npm run start&lt;/code&gt; locally, a new &lt;code&gt;README.md&lt;/code&gt; file will be generated, including any changes that come from the API and RSS feeds. But I shouldn't have to do this manually every time I want to change something, right? So what can we do?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701642047536%2FARFND1eby.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701642047536%2FARFND1eby.jpg" alt="A Meme from Money Heist showing the casts in a classroom"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's where CI/CD and cron jobs come in.&lt;/p&gt;




&lt;h3&gt;
  
  
  CI/CD Pipeline
&lt;/h3&gt;

&lt;p&gt;If you're new to this, CI/CD (which means Continuous Integration / Continuous Delivery or Deployment) is a process used in software engineering to merge code and automate specific repeated sequence of tasks (e.g., tests) that are required before and/or after deploying a software (e.g., releases) for users to access. In our case, we want to run the &lt;code&gt;npm run start&lt;/code&gt; command on the cloud repeatedly on a fixed day/time and push the updated README file to the special GitHub repository using Git. This way, anytime a user views the GitHub profile, they see the latest content (the latest deployed version of the README based on the schedule). If there's an error, the process is expected to fail and return the errors in the log file.&lt;/p&gt;

&lt;p&gt;This is a basic use case of CI/CD. For more extensive software, you would have a more complex pipeline (managed mainly by DevOps or SRE engineers) handling things like running unit/integration tests, updating data, release notes, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cron Jobs Scheduling
&lt;/h3&gt;

&lt;p&gt;The scheduling would be handled with something called a Cron Job. This is the standard method of scheduling specific tasks on a server at fixed times. At the right time or interval, certain tasks (jobs) will be executed. If you're new to this concept, you might be able to visualize how this will work based on our Profile README use case. It doesn't make sense to update the README file every second since I'm not publishing new content every second. To avoid wasting resources, setting up a Cron Job to execute the logic daily or even weekly is ideal. With this, a user will still get the most recent content. You can adjust the schedule to fit your needs if you're doing this for another use case.&lt;/p&gt;

&lt;p&gt;Cron jobs are composed of expressions. An expression includes a string of five fields (&lt;code&gt;* * * * *&lt;/code&gt;) which will contain numbers and some special characters. The character asterisk (**&lt;strong&gt;*) represents **any value&lt;/strong&gt;, comma (&lt;strong&gt;,&lt;/strong&gt;) represents &lt;strong&gt;a list of values&lt;/strong&gt;, hyphen (&lt;strong&gt;-&lt;/strong&gt;) represents &lt;strong&gt;a range of values&lt;/strong&gt;, and slash (&lt;strong&gt;**) represents **a step of values&lt;/strong&gt;. Each field represents the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Minute (0 - 59).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hour (0 - 23).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Day of the month (1 - 31).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Month (1 - 12).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Day of the week (0 - 6 with 0 being Sunday).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A cron expression &lt;code&gt;* * * * *&lt;/code&gt; will mean run every minute, &lt;code&gt;*/30 * * * *&lt;/code&gt; will mean run every 30 minutes, &lt;code&gt;*/30 7 * * *&lt;/code&gt; will mean run every 30 minutes between 07:00 and 07:59, &lt;code&gt;*/30 7-10 * * *&lt;/code&gt; will mean run every 30 minutes between 07:00 and 10:59, &lt;code&gt;* 12-18 * * *&lt;/code&gt; will mean run every minute between 12:00 and 18:00, &lt;code&gt;0 12-18 * * *&lt;/code&gt; will mean run hourly between 12:00 and 18:00, &lt;code&gt;0 12-18 5 5 *&lt;/code&gt; will mean run hourly between 12:00 and 18:00 on the 5th day of March only, &lt;code&gt;0 12 * * *&lt;/code&gt; will mean run daily at 12:00, etc. There are so many permutations, and if you're interested, you can create, test, and practice different cron expressions using services like &lt;a href="https://cronexpressiontogo.com?utm_source=https://blog.bolajiayodeji.com" rel="noopener noreferrer"&gt;Cron Expression To Go&lt;/a&gt; or &lt;a href="https://crontab.guru?utm_source=https://blog.bolajiayodeji.com" rel="noopener noreferrer"&gt;Crontab Guru&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Actions
&lt;/h3&gt;

&lt;p&gt;You can set up a CI/CD pipeline using several tools like CircleCI, Travis CI, GitHub Actions, etc. We will use GitHub Actions for this use case since it's provided by the platform we're already using (but you can achieve the same with the others). GitHub Actions allows you to automate your build, test, and deployment pipeline with workflows inside a GitHub repository. These workflows can run on every pull request to your repository, merged pull requests, cron jobs, etc. You can learn more about GitHub Actions by reading &lt;a href="https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions?utm_source=https://blog.bolajiayodeji.com" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; on GitHub Docs.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;.github/workflows/build.yml&lt;/code&gt;, add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Profile README&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;6&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*"&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout Repo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;18"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Rebuild README.md File&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run start&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Commit and Push if Changed&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
          &lt;span class="s"&gt;git add .&lt;/span&gt;
          &lt;span class="s"&gt;git diff&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.email "mailtobolaji+actionsbot@gmail.com"&lt;/span&gt;
          &lt;span class="s"&gt;git config --global user.name "BA Actions Bot"&lt;/span&gt;
          &lt;span class="s"&gt;git commit -m "docs: auto-update README.md" -a || exit 0&lt;/span&gt;
          &lt;span class="s"&gt;git push&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, I configure GitHub Actions to set the name of the build, set the determinant of the pipeline (a cron schedule), set the cron schedule to run 06:00 AM daily (GitHub’s cron schedule runs with the UTC timezone), add some steps, install all the required dependencies, run the &lt;code&gt;npm start&lt;/code&gt; command, generate the new &lt;code&gt;README.md&lt;/code&gt; file, and push the changes using Git (if there are any changes in the file). If no changes exist, the process terminates, and no commit is pushed.&lt;/p&gt;

&lt;p&gt;If you push the entire code to GitHub, the build will run automatically in GitHub Actions upon each push. But also, it will run on its own every day as scheduled. You can see the log of all builds in the "Actions" tab of the repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701706236607%2F3gwLaWAZa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701706236607%2F3gwLaWAZa.png" alt="A screenshot of a GitHub Actions log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701706325157%2FRsUVQ3VaB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701706325157%2FRsUVQ3VaB.png" alt="A screenshot of a GitHub Actions log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, kindly note that you might experience some delays with GitHub Actions for the first time. Initially, I chose 00:00 as my cron schedule, but it wasn't working. &lt;a href="https://github.com/orgs/community/discussions/52477" rel="noopener noreferrer"&gt;Research&lt;/a&gt; showed that sometimes it fails during peak hours, like the first hour of the day when usage is high. I switched to 06:00, which still failed but started working fine the next day or so. In summary, GitHub Actions can be unpredictable for cron jobs, and you can use a dedicated infrastructure if you need a reliable execution at an exact time. But for this use case, it works just fine once it gets stable (nothing critical is going on here).&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom GitHub Bot Account
&lt;/h3&gt;

&lt;p&gt;If you observed, I used a custom &lt;code&gt;user.email&lt;/code&gt; and &lt;code&gt;user.name&lt;/code&gt; when setting up the GitHub actions push step. If you use a random email, it will push to GitHub with a non-existent account (no profile picture will be shown). My first thought was to use my actual GitHub account email that will push the changes as myself. But to make things much more neat, I created a &lt;a href="https://github.com/ba-actions-bot" rel="noopener noreferrer"&gt;new GitHub account&lt;/a&gt; that acts as a bot. This way, I can tell all the commits that were auto-generated from the script from mine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701710367914%2Fxv95vopOV.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701710367914%2Fxv95vopOV.png" alt="Screenshot of a GitHub commits page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create the account, you can use your existing Gmail (if you don't have Gmail, use any email). Google allows you to create email aliases and receive emails from all in your inbox. All you must do is add a plus (+) sign after your email address and some custom text. Generally, I use this hack to create multiple email aliases for my Gmail so I can easily track specific emails based on context (e.g. if the email is &lt;a href="mailto:bolaji@gmail.com"&gt;bolaji@gmail.com&lt;/a&gt;, an alias can be &lt;a href="mailto:bolaji+actionsbot@gmail.com"&gt;bolaji+actionsbot@gmail.com&lt;/a&gt;). You're good to go once you create the account and set a nice name/profile picture. If you use this email to configure Git in the GitHub Actions, it will reflect accordingly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701710606078%2FSqDsscFWC.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701710606078%2FSqDsscFWC.png" alt="Screenshot of a GitHub commits page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS: if you choose to do this with a Gmail alias, ensure to save the password somewhere because if you forget the password and need to log in (maybe to change the profile picture), you won't be able to use the "Forget password" feature with a Gmail alias email address. GitHub's form validation filters it out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701710836502%2F7SARlHKJI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701710836502%2F7SARlHKJI.png" alt="GitHub's forgot password page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, to solve this, manually change the "Backup email address" option to "Only allow primary email" in GitHub's dashboard (Settings &amp;gt; Emails).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701712234763%2F7HILljuwI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701712234763%2F7HILljuwI.png" alt="GitHub's email seetings page"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;That's about it! Now, you've learned how to automate scripts with CI/CD. If you're new to many of the concepts discussed in this tutorial, you should have learned some new things you can expand on. You can also extend the ideas here and customize the script to do anything you want it to. Just find a data source and do your thing.&lt;/p&gt;

&lt;p&gt;I'm keen to see what you build with this, so please leave a comment with a link to your GitHub README Profile if you do something like this. Remember that this goes beyond markdown files; you can use the automated script idea to do anything else!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701721829132%2FO76tPm8r9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1701721829132%2FO76tPm8r9.png" alt="Screenshot of my GitHub profile page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm happy with the results, and I look forward to making more changes in the future as the need arises :). Thanks for reading this far; cheers!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>github</category>
      <category>automation</category>
    </item>
    <item>
      <title>Building an Ecommerce Store with Nextjs and Commerce Layer Demo Store</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Sun, 22 Jan 2023 17:00:00 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/building-an-ecommerce-store-with-nextjs-and-commerce-layer-demo-store-37hp</link>
      <guid>https://dev.to/bolajiayodeji/building-an-ecommerce-store-with-nextjs-and-commerce-layer-demo-store-37hp</guid>
      <description>&lt;p&gt;Have you ever wanted to learn how to build an ecommerce website as a developer? Look no further! In this article, I’ll walk you through the process of building a sleek, modern, and user-friendly conference swag digital store using composable commerce APIs, micro-frontends, and the Commerce Layer Nextjs Demo Store project. With the help of this powerful tool, you'll be able to create a visually appealing and functional international ecommerce website that is optimized for success. I'll show you step-by-step how to set up your store, add commerce data, and deploy your website in no time. Let’s get started!&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%2Fpnkists2ckb5we7qbk7a.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%2Fpnkists2ckb5we7qbk7a.png" alt="A screenshot of the final demo store" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Some JavaScript, command-line, and API knowledge are required.&lt;/li&gt;
&lt;li&gt;A working programming IDE (I use vscode; you can also try it).&lt;/li&gt;
&lt;li&gt;A stable internet connection.&lt;/li&gt;
&lt;li&gt;Optionally, you can study these &lt;a href="https://commercelayer.io/docs/data-model" rel="noopener noreferrer"&gt;data models&lt;/a&gt; to understand the key Commerce Layer API entities, their mutual relationships, and common usage.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction to Composable Commerce
&lt;/h2&gt;

&lt;p&gt;Before we proceed, let’s understand what the concept “composable” means. Before now, ecommerce websites were built with a monolithic architecture where all components (frontend, backend, content, and commerce data) were coupled into one system. Over time, this approach posed different weaknesses related to speed, flexibility, scalability, security, modularity, etc. Most importantly, it became difficult for different sub-teams in an engineering team to effectively build in development and collaborate on the product—leading to a poor developer experience. All these weaknesses directly affect the sales and customer retention part of an ecommerce business, which shouldn’t be the case. Hence, there was the rise of a better approach that allows for an independent and agnostic setup for all teams (frontend, backend, content, etc.) and effective product development flow. This approach, called “composable commerce,” allowed for a better developer experience, more room for creativity and innovation from each team, more room for adapting to new market opportunities, and eventually, customer satisfaction, increased revenue, and customer retention.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://commercelayer.io/docs/core-concepts/composable-commerce" rel="noopener noreferrer"&gt;Composable commerce&lt;/a&gt; allows developers to review, select, and utilize various available commerce solutions as required to satisfy specific business needs in the different sub-teams of the engineering team. Developers can compose their development stack by selecting best-of-breed tools from &lt;a href="https://www.postman.com/explore/apis" rel="noopener noreferrer"&gt;API-first solutions&lt;/a&gt;, headless solutions, composable microservices, or even microfrontends. If any of these terms are unfamiliar, you can do a quick Google search to learn more about them. Generally, a composable commerce solution includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The front-end presentation layer decoupled from the backend logic.&lt;/li&gt;
&lt;li&gt;Individual components (autonomously developed, deployed, and managed) targeted toward specific business requirements.&lt;/li&gt;
&lt;li&gt;APIs connecting each of these individual components.&lt;/li&gt;
&lt;li&gt;Integration with reliable API-first external services.&lt;/li&gt;
&lt;li&gt;SAAS and cloud computing services.&lt;/li&gt;
&lt;li&gt;Real-time data shared between applications with webhooks.&lt;/li&gt;
&lt;li&gt;Possibilities to build an independent and agnostic internal application on top of the existing data and composable architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The beauty of the composable commerce architecture is that you can distribute your ecommerce service anywhere your customer wants them (either on mobile, web, smart devices, CLIs, etc.) so long the envisaged sales channel allows API mechanisms. For brands and developers, the options are numerous; for example, you can go as easy as making a static HTML website shoppable using a &lt;a href="https://github.com/commercelayer/drop-in.js" rel="noopener noreferrer"&gt;dropin library&lt;/a&gt; to power certain transactional functionalities or building a fully functional ecommerce website with commerce platforms like Commerce Layer and dev tools like the &lt;a href="https://github.com/commercelayer/demo-store" rel="noopener noreferrer"&gt;Demo Store&lt;/a&gt; project (which we will do in this article!).&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%2F2v1odjiw1ftgdsx3t3hq.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%2F2v1odjiw1ftgdsx3t3hq.png" alt="Illustration of an ecommerce website showing components powered by commerce APIs" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;The Demo Store project is a static ecommerce solution with no third-party services required, so you can easily tailor your own with different levels of customization. As such, even content is stored as JSON files. The Demo Store comes with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A full product catalog management with taxonomies and taxons.&lt;/li&gt;
&lt;li&gt;Single product variants management.&lt;/li&gt;
&lt;li&gt;Multi-language capabilities to make selling internationally easier.&lt;/li&gt;
&lt;li&gt;A built-in search engine with a faceted search (filtered search).&lt;/li&gt;
&lt;li&gt;An extensive set of features provided out of the box by Commerce Layer APIs (multiple currency price lists, inventory models that support multiple stock locations and fulfillment strategies, market-specific payment gateways, delivery options, carrier accounts, etc.).&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%2Fqmj3380ezecknv2f6ypt.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%2Fqmj3380ezecknv2f6ypt.png" alt="A screenshot of the demo store's product page" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the sections below, I’d show you how to set up and configure your own ecommerce store using the demo store project. Ready? Let’s go!&lt;/p&gt;

&lt;h3&gt;
  
  
  Get your API Credentials
&lt;/h3&gt;

&lt;p&gt;The demo store project is powered by Commerce Layer— a composable commerce API for developers and brands that you can use to build an international ecommerce website to process millions of orders. All the amazing API resources, Nextjs, TypeScript, and other tools were used in building the Demo Store ecommerce project. You can explore these &lt;a href="https://www.postman.com/commercelayer" rel="noopener noreferrer"&gt;Postman collections&lt;/a&gt; to test specific resources and see how they all work. To get started, all requests to Commerce Layer API must be authenticated with an &lt;a href="https://oauth.net/2/" rel="noopener noreferrer"&gt;OAuth2&lt;/a&gt; bearer token. You need to execute an authorization flow using a valid application type as the client to get an access token. Each application type has its usage, authentication flow, and permissions. The application type can be authenticated with different authorization grant flows using the available authorization grant types as described in the table 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%2Ff7ubdf2cmez4c76xgcfs.jpeg" 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%2Ff7ubdf2cmez4c76xgcfs.jpeg" alt="A screenshot of the application types table comparison" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kindly create a Commerce Layer account &lt;a href="https://dashboard.commercelayer.io/sign_up" rel="noopener noreferrer"&gt;here&lt;/a&gt;, follow the onboarding tutorial to create an organization, and read &lt;a href="https://docs.commercelayer.io/core/applications#creating-an-application" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; to learn how to create a &lt;code&gt;sales_channel&lt;/code&gt; and &lt;code&gt;integration&lt;/code&gt; application type. When you are done creating them, save your organization slug, base endpoint, and the generated &lt;code&gt;CLIENT_ID&lt;/code&gt; and &lt;code&gt;clientSecret&lt;/code&gt; credential—we will use this to configure the demo store and seed some demo data shortly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install and Configure the Demo Store
&lt;/h3&gt;

&lt;p&gt;The Demo Store project is a GitHub template that uses the &lt;a href="https://github.com/commercelayer/demo-store-core" rel="noopener noreferrer"&gt;demo-store-core&lt;/a&gt; repository as a &lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Submodules" rel="noopener noreferrer"&gt;git submodule&lt;/a&gt;. This will retain the features, look, and feel of the default Demo Store. With this, you won't have to care about the whole source code but instead focus on your data/content and easily get free updates with almost no risk just by running the &lt;code&gt;git submodule update --remote &amp;amp;&amp;amp; npm install&lt;/code&gt; command. Kindly follow the steps below to get started:&lt;/p&gt;

&lt;p&gt;→ Click on the "Use this template" button from the &lt;a href="https://github.com/commercelayer/demo-store" rel="noopener noreferrer"&gt;demo-store&lt;/a&gt;'s homepage on GitHub, as seen in 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%2Fsg5ifbvk787l9qk08bwk.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%2Fsg5ifbvk787l9qk08bwk.png" alt="A screenshot of the " width="800" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;→ Run the following commands to clone the forked repository to your local computer and install the required dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;your-repository-url&amp;gt; my-new-demo-store
&lt;span class="nb"&gt;cd &lt;/span&gt;my-new-demo-store
git submodule update &lt;span class="nt"&gt;--init&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Run the following commands to copy all the required environment variables and data files into your demo store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./demo-store-core/packages/website/data/json ./data/json

&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./demo-store-core/packages/website/locales ./data/locales

&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./demo-store-core/packages/website/config ./config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Create a &lt;code&gt;.env.local&lt;/code&gt; file and add the following variables, including your previously created &lt;code&gt;sales_channel&lt;/code&gt; application credentials (Client ID and Base endpoint):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SITE_URL=http://localhost:3000
NEXT_PUBLIC_CL_CLIENT_ID=coF7ofOKxTlbYfN...
NEXT_PUBLIC_CL_ENDPOINT=https://your-demo-store.commercelayer.io

NEXT_PUBLIC_JSON_DATA_FOLDER=../../../data/json/
NEXT_PUBLIC_LOCALES_DATA_FOLDER=../../../data/locales/
NEXT_PUBLIC_CONFIG_FOLDER=../../../config/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Seed Organization with Demo Data
&lt;/h3&gt;

&lt;p&gt;To create an ecommerce store, you need to add some commerce resources to your organization. Suppose this is your first time doing something like this. In that case, you can easily seed your organization automatically with demo data and use that to learn about the key commerce resources required. When you’re ready, you can add the actual data for your ecommerce store. Kindly follow the steps below to seed your newly created Commerce Layer organization:&lt;/p&gt;

&lt;p&gt;→ Install the &lt;a href="https://github.com/commercelayer/commercelayer-cli" rel="noopener noreferrer"&gt;Commerce Layer CLI&lt;/a&gt; using the command (this will give you access to the &lt;code&gt;cl&lt;/code&gt; command):&lt;br&gt;
&lt;/p&gt;

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

or

yarn global add @commercelayer/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Install the &lt;a href="https://github.com/commercelayer/commercelayer-cli-plugin-seeder" rel="noopener noreferrer"&gt;seeder plugin&lt;/a&gt; and the &lt;a href="https://github.com/commercelayer/commercelayer-cli-plugin-imports" rel="noopener noreferrer"&gt;imports plugin&lt;/a&gt; using the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cl plugins:install seeder
cl plugins:install imports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Log into the CLI with your previously created &lt;code&gt;integration&lt;/code&gt; application credentials like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cl applications:login &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--clientId&lt;/span&gt; Oy5F2TbPYhOZsxy1tQd9ZVZ... &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--clientSecret&lt;/span&gt; 1ZHNJUgn_1lh1mel06gGDqa... &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--organization&lt;/span&gt; your-demo-store &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--alias&lt;/span&gt; cli-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Run the command below to populate your organization with all the resources you need to build a multi-market ecommerce with Commerce Layer (this includes markets, SKUs, prices, inventory, stock locations, etc.):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run seeder:seed &lt;span class="nt"&gt;-ws&lt;/span&gt; &lt;span class="nt"&gt;--if-present&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ If the command above fails with errors (usually because of unstable internet), you can seed your organization with sample data using the command (but this process will take a bit more time):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cl seeder:seed &lt;span class="nt"&gt;-b&lt;/span&gt; custom &lt;span class="nt"&gt;-n&lt;/span&gt; demo_store_full &lt;span class="nt"&gt;-u&lt;/span&gt; ./demo-store-core/packages/setup/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ The &lt;code&gt;data/json/countries.json&lt;/code&gt; file contains a list of available countries for your ecommerce store. Choose the countries you want to start with and replace all findings of &lt;code&gt;"market": xxxxx&lt;/code&gt; with the valid market scopes from your organization (you can find these in the &lt;code&gt;sales_channel&lt;/code&gt; application you created earlier).&lt;/p&gt;

&lt;p&gt;→ Now, you can start the development server and visit &lt;code&gt;http://localhost:3000&lt;/code&gt; to preview your ecommerce store like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fqfmbby03coox7daap80d.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%2Fqfmbby03coox7daap80d.png" alt="A screenshot of the demo store's search page" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You must first select a country when you visit the homepage. When you select the United States, for example, you will be redirected to the &lt;a href="http://localhost:3000/it-US/" rel="noopener noreferrer"&gt;&lt;code&gt;http://localhost:3000/en-US/&lt;/code&gt;&lt;/a&gt; path, which will return a shopping experience from the United States market in Commerce Layer with English content translations. Changing the language to French, for example, will redirect to a &lt;code&gt;http://localhost:3000/fr-US&lt;/code&gt; page. Changing the country to Italy will return a shopping experience from the Europe market in Commerce Layer and redirect to a &lt;code&gt;http://localhost:3000/fr-IT&lt;/code&gt; page. You can play around with it for other countries and languages.&lt;/p&gt;

&lt;p&gt;This is a fully-functional international ecommerce website with a multi-market setup, facet search, cart, and checkout in just a few minutes and fewer development efforts. Also, if you already have an existing CMS with content, you can still use that to generate the required content JSON file (we will show you how in a follow-up tutorial 😉). Now, you can go ahead and make transactional changes for each market in Commerce Layer, and your demo store will return the right experience to your users. Isn’t this cool?&lt;/p&gt;

&lt;p&gt;In the next section, you will learn how to do more by customizing your store and adding more translations, pages, countries, and other commerce resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customizing your Demo Store
&lt;/h3&gt;

&lt;p&gt;The Demo Store project is built around three main data elements stored as JSON files to decouple them from any third-party services you might want to add yourself. To customize your store, you'll have to create and manage these files.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;content&lt;/strong&gt; JSON files are located in the &lt;code&gt;data/json/&lt;/code&gt; directory with different structured text and image content (here is &lt;a href="https://github.com/BolajiAyodeji/conf-swag-demo-store/tree/master/data/json" rel="noopener noreferrer"&gt;a sample&lt;/a&gt; from the finished code).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;locale&lt;/strong&gt; JSON files are located in the &lt;code&gt;data/locales/&lt;/code&gt; directory with a collection of language translation files (here is &lt;a href="https://github.com/BolajiAyodeji/conf-swag-demo-store/tree/master/data/locales" rel="noopener noreferrer"&gt;a sample&lt;/a&gt; from the finished code with french and Italian translations).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;configuration&lt;/strong&gt; files are located in the &lt;code&gt;config/&lt;/code&gt; directory with some JS files that change the behavior of search facets and variants swatching for products with multiple variants (which in turn means the existence of multiple SKUs).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you are done with any change, always ensure to check that everything is correct by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test&lt;/span&gt;:data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can look at &lt;a href="https://github.com/BolajiAyodeji/conf-swag-demo-store" rel="noopener noreferrer"&gt;the finished code&lt;/a&gt; to see all the extra pages and translation changes added to the demo conference swag ecommerce website. Alternatively, if you need to fully customize your store (behavior, UI, UX, etc.), then all you have to do is fork the &lt;a href="https://github.com/commercelayer/demo-store-core" rel="noopener noreferrer"&gt;demo-store-core&lt;/a&gt; repository, which contains the source code, follow the instructions to set things up locally and configure it as earlier discussed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the Demo Store
&lt;/h2&gt;

&lt;p&gt;There are two things you need to do before you deploy your store using your favorite hosting platforms (e.g., Netlify, Vercel, GitHub Pages, Cloudflare Pages, etc.):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add all the environment variables you currently have in &lt;code&gt;.env.local&lt;/code&gt; to the deployment service you'll use to run the build.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decide if you want to use static site generation (SSG) or server-side rendering (SSR) in production.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The next sections will outline the steps required for each option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Static site generation (SSG)
&lt;/h3&gt;

&lt;p&gt;→ Add this in addition to other variables in your env file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_DATA_FETCHING=ssg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Run &lt;code&gt;npm run export&lt;/code&gt; to create a static optimized production build of your application.&lt;/p&gt;

&lt;p&gt;→ Copy the folder in &lt;code&gt;demo-store-core/packages/website/out&lt;/code&gt; to your preferred static hosting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-side rendering (SSR)
&lt;/h3&gt;

&lt;p&gt;→ Add this in addition to other variables in your env file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_DATA_FETCHING=ssr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Set the output directory in your deployment service to &lt;code&gt;demo-store-core/packages/website/.next&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;→ Set &lt;code&gt;npm run build&lt;/code&gt; as your build command to create an optimized production build of your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD Deployment
&lt;/h3&gt;

&lt;p&gt;You can use the same steps and options if you set up CI/CD deployment directly from a GitHub or GitLab repository. For example, you can create a &lt;code&gt;netlify.toml&lt;/code&gt; file for Netlify with SSG like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build]&lt;/span&gt;
  &lt;span class="py"&gt;command&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"npm run export"&lt;/span&gt;
  &lt;span class="py"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"demo-store-core/packages/website/out"&lt;/span&gt;

&lt;span class="nn"&gt;[build.processing]&lt;/span&gt;
  &lt;span class="py"&gt;skip_processing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nn"&gt;[build.environment]&lt;/span&gt;
  &lt;span class="py"&gt;NEXT_PUBLIC_JSON_DATA_FOLDER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"../../../data/json/"&lt;/span&gt;
  &lt;span class="py"&gt;NEXT_PUBLIC_LOCALES_DATA_FOLDER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"../../../data/locales/"&lt;/span&gt;
  &lt;span class="py"&gt;NEXT_PUBLIC_CONFIG_FOLDER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"../../../config/"&lt;/span&gt;

&lt;span class="nn"&gt;[template.environment]&lt;/span&gt;
  &lt;span class="py"&gt;SITE_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://your-demo-store.netlify.app"&lt;/span&gt;
  &lt;span class="py"&gt;NEXT_PUBLIC_CL_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"coF7ofOKxTlbYfNNe..."&lt;/span&gt;
  &lt;span class="py"&gt;NEXT_PUBLIC_CL_ENDPOINT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://your-demo-store.commercelayer.io"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or a &lt;code&gt;vercel.json&lt;/code&gt; file for Vercel with SSR like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"buildCommand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputDirectory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"demo-store-core/packages/website/.next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ENABLE_EXPERIMENTAL_COREPACK"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"NEXT_PUBLIC_DATA_FETCHING"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ssr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"NEXT_PUBLIC_JSON_DATA_FOLDER"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../../../data/json/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"NEXT_PUBLIC_LOCALES_DATA_FOLDER"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../../../data/locales/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"NEXT_PUBLIC_CONFIG_FOLDER"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../../../config/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"SITE_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://conf-swag-demo-store.vercel.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"NEXT_PUBLIC_CL_CLIENT_ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"coF7ofOKxTlbYfNNe..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"NEXT_PUBLIC_CL_ENDPOINT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://your-demo-store.commercelayer.io"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PS: If you use this option, please make sure that your Commerce Layer API credentials are private. The API credentials in the &lt;code&gt;netlify.toml&lt;/code&gt; or &lt;code&gt;vercel.json&lt;/code&gt; files should only be added to a private repository. You should always add API credentials directly to your deployment service. I added mine to the repository just for educational purposes.&lt;/p&gt;

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

&lt;p&gt;And that’s a wrap!&lt;/p&gt;

&lt;p&gt;I hope you’ve found this tutorial useful and have learned how composable commerce and international websites work. Feel free to expand your knowledge by researching more, customizing your ecommerce store, integrating with other third-party services, adding more commerce data to your Commerce Layer organization, and exploring Commerce Layer’s other suite of &lt;a href="https://commercelayer.io/developers" rel="noopener noreferrer"&gt;developer tools&lt;/a&gt;. You can go ahead and use this project to start selling conference swags or any products and receive orders for free (courtesy of the Commerce Layer free &lt;a href="https://commercelayer.io/pricing" rel="noopener noreferrer"&gt;Developer plan&lt;/a&gt;) 😃.&lt;/p&gt;

&lt;p&gt;I’d also love to see what you build with this, so please feel free to share what you’ve built and let me know what you think about the tutorial in the comment section or in &lt;a href="https://commercelayer.io/developers" rel="noopener noreferrer"&gt;Commerce Layer's Slack community&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to Build an International Ecommerce Website with Sanity and Commerce Layer</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Mon, 11 Apr 2022 13:25:52 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/how-to-build-an-international-ecommerce-website-with-sanity-and-commerce-layer-555a</link>
      <guid>https://dev.to/bolajiayodeji/how-to-build-an-international-ecommerce-website-with-sanity-and-commerce-layer-555a</guid>
      <description>&lt;p&gt;One of the greatest benefits of composable, headless commerce is the flexibility it introduces to the developer experience of building shopping experiences. Decoupling website content and commerce data makes it easier for content and commerce teams of experts to work independently and more efficiently. With Commerce Layer, content managers can work with a best-of-breed headless CMS like Sanity, merchants can build their inventory in Commerce Layer, and developers can build with any stack in their most preferred programming language while utilizing Commerce Layer’s APIs.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will learn how we built the &lt;a href="https://github.com/commercelayer/sanity-template-commercelayer"&gt;Commerce Layer Starter&lt;/a&gt; with Nextjs, Sanity studio, and deployed it to Netlify. At the end of the tutorial, you should be able to set up and build your own 1-click sanity starter with ease or integrate with Commerce Layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Git installed (Learn how to install Git &lt;a href="https://github.com/git-guides/install-git"&gt;here&lt;/a&gt; if you haven't already).&lt;/li&gt;
&lt;li&gt;Node and NPM installed (Learn how to install Nodejs &lt;a href="https://nodejs.org/en/download/package-manager/"&gt;here&lt;/a&gt; if you haven't already).&lt;/li&gt;
&lt;li&gt;Basic knowledge of how to use the terminal.&lt;/li&gt;
&lt;li&gt;Basic knowledge of NPM.&lt;/li&gt;
&lt;li&gt;A grin on your face 😉.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction to Commerce Layer
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://commercelayer.io"&gt;Commerce Layer&lt;/a&gt; is a transactional commerce API and order management for international brands. It lets you make any digital experience shoppable, anywhere. You can build a multi-language website with Shopify, Contentful, WordPress, or any other CMS you already love. Then, add Commerce Layer for multi-currency prices, distributed inventory, localized payment gateways, promotions, orders, subscriptions, and more.&lt;/p&gt;

&lt;p&gt;Unlike traditional solutions, &lt;a href="https://commercelayer.io/why"&gt;Commerce Layer was built for the new era&lt;/a&gt;. It natively supports the most modern development workflows, such as the Jamstack. Ecommerce businesses can integrate Commerce Layer with a single backend and serve on multiple presentation layers enabling them to build outstanding shopping experiences, go headless, and scale their business globally. You can check out our &lt;a href="https://commercelayer.io/developers/"&gt;developer resources&lt;/a&gt; to learn more and get started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZH28x7Wz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649777866598/IrP5NR4c0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZH28x7Wz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649777866598/IrP5NR4c0.png" alt="A screenshot of Commerce Layer's website homepage" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Sanity Studio
&lt;/h2&gt;

&lt;p&gt;The Sanity studio is an open-source content management system built with React.js. It offers rapid configuration, free form customization, reusable structured content, a comfortable editor, real-time collaboration, toolkits, plugins, and more features to enable you to create the best content workflow.&lt;/p&gt;

&lt;p&gt;Sanity provides the possibility to create starter templates that can be re-used by developers easily. The starter is primarily a repository hosted on GitHub that contains some meta-information, demo content, schema, and frontend(s) that will end up in a new repository when a developer installs the starter through &lt;a href="https://www.sanity.io/starters"&gt;sanity.io/starters&lt;/a&gt;. When a developer installs the starter, Sanity creates a new project on Sanity and a new repository on GitHub with the starter code, attaches a new Sanity &lt;code&gt;datasetId&lt;/code&gt; to the starter, and deploys the project to Netlify simultaneously.&lt;/p&gt;

&lt;p&gt;Generally, a sanity starter can include a Sanity studio, a frontend application, both or multiple frontends and studios. For the purpose of this tutorial, we will create a starter that will include a studio and frontend. Our starter will include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An ecommerce storefront built with Nextjs and &lt;a href="https://github.com/commercelayer/commercelayer-react-components"&gt;Commerce Layer react components library&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;International shopping capabilities powered by &lt;a href="https://docs.commercelayer.io/developers/v/api-reference/"&gt;Commerce Layer APIs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Some ecommerce data imported using the &lt;a href="https://github.com/commercelayer/commercelayer-cli"&gt;Commerce Layer CLI&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Structured content on Sanity studio.&lt;/li&gt;
&lt;li&gt;Localization support.&lt;/li&gt;
&lt;li&gt;Deployment configuration settings to Netlify.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uMoAgv4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682532486/yZQ5D5vgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uMoAgv4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682532486/yZQ5D5vgy.png" alt="A GitHub repo cover image" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity Starter Project Structure
&lt;/h2&gt;

&lt;p&gt;Sanity has a defined specification for starters which includes some required files and directories. These specifications provide information about the starter to developers using the starter and make the project function as a reusable starter. Below is the folder structure of a Sanity project with required files and directories (without any frontend added):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;├── .sanity-template
├── .sanity-template/assets
├── .sanity-template/data
├── .sanity-template/manifest.json
├── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.sanity-template&lt;/code&gt;&lt;/strong&gt; is the root directory where all meta-information for using this repository as a template on &lt;a href="http://sanity.io/starters"&gt;sanity.io/starters&lt;/a&gt; is stored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.sanity-template/assets&lt;/code&gt;&lt;/strong&gt; is the directory for storing assets related to displaying information about the starter. In this case, preview images for the overall project and for each site the starter contains.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.sanity-template/data&lt;/code&gt;&lt;/strong&gt; is the directory to store a Sanity dataset export if you want the starter to launch with some demo content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.sanity-template/manifest.json&lt;/code&gt;&lt;/strong&gt; is the JSON file containing details about the Starter as well as deployment information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/strong&gt; is the markdown file for this project that will be displayed on the Create page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a finished starter project, the root of the project should contain all deployable code, including the frontend and studio. Generally, a project spun from a starter is split into three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The root for all frontend code&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;/studio&lt;/code&gt; directory for all studio code.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;.sanity-template&lt;/code&gt; for all starter meta-information.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is a sample from the &lt;a href="https://github.com/commercelayer/sanity-template-commercelayer"&gt;Commerce Layer sanity starter&lt;/a&gt; as seen in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4WZysLBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682579244/W92y68XXE.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4WZysLBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682579244/W92y68XXE.jpg" alt="sanity-starter-github-repo-screenshot" width="800" height="951"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Built the Commerce Layer Sanity Starter
&lt;/h2&gt;

&lt;p&gt;In this section, you will learn how we built a starter with an ecommerce application with transactional functionalities powered by &lt;a href="https://commercelayer.io/"&gt;Commerce Layer&lt;/a&gt; APIs, structured content on Sanity, imported seed data, and deployment configuration to Netlify. If you want to follow along with the guide, you can take a look at the finished project on GitHub &lt;a href="https://github.com/commercelayer/sanity-template-commercelayer"&gt;here&lt;/a&gt; or even install the starter &lt;a href="https://www.sanity.io/create?template=commercelayer/sanity-template-commercelayer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a sequential breakdown of all the steps taken to develop a starter:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣  Setup a new Sanity project using the Sanity CLI
&lt;/h3&gt;

&lt;p&gt;Sanity has a command-line interface that we can use to interact with Sanity, create new projects, manage datasets, import data, and much more from the CLI. We'll use this CLI to set up a new sanity project following the steps below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1: Install the CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the command below to install the Sanity CLI.&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;&lt;strong&gt;2: Create a new project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the command below to bootstrap a new project which will log you into Sanity, create a new project, set up a dataset, and generate the files needed to run the studio environment locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sanity init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3: Run the studio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the command below to build the initial JavaScript code required to run the studio, and start a local web server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sanity start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The studio should now run on &lt;code&gt;[localhost:3333](http://localhost:3333)&lt;/code&gt;. You can always run &lt;code&gt;sanity help&lt;/code&gt; to get an overview of other available and useful commands in the Sanity CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣  Content modeling for the created Sanity studio
&lt;/h3&gt;

&lt;p&gt;Now that we understand how Sanity works and have set up a new sanity project, let's structure our sanity studio schema. Sanity schema defines how your content should be modeled, and this structure reflects in the studio UI. The schema describes the different field types a document consists of. Sanity uses the &lt;code&gt;schema.js&lt;/code&gt; file in the &lt;code&gt;/schemas&lt;/code&gt; directory to determine the content model of the project.&lt;/p&gt;

&lt;p&gt;With Sanity, you define a block of content as a document or split your documents into modules and import them into the parent &lt;code&gt;schema.js&lt;/code&gt; file. Generally, there are three categories of Sanity schema types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Document types (&lt;a href="https://www.sanity.io/docs/document-type"&gt;document&lt;/a&gt; and other published custom schemas)&lt;/li&gt;
&lt;li&gt;Primitive types (e.g., &lt;a href="https://www.sanity.io/docs/boolean-type"&gt;boolean&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/string-type"&gt;string&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/text-type"&gt;text&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/number-type"&gt;number&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/array-type"&gt;array&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/datetime-type"&gt;datetime&lt;/a&gt;, and &lt;a href="https://www.sanity.io/docs/url-type"&gt;URL&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Object types (e.g., &lt;a href="https://www.sanity.io/docs/object-type"&gt;object&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/block-type"&gt;block&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/span-type"&gt;span&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/reference-type"&gt;reference&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/slug-type"&gt;slug&lt;/a&gt;, &lt;a href="https://www.sanity.io/docs/image-type"&gt;image&lt;/a&gt;, and &lt;a href="https://www.sanity.io/docs/file-type"&gt;file&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find all of the Sanity’s types in this &lt;a href="https://www.sanity.io/docs/schema-types"&gt;reference documentation&lt;/a&gt; or learn how to structure your content model based on your needs by reading &lt;a href="https://www.sanity.io/guides/introduction-to-content-modeling"&gt;this comprehensive guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the Commerce Layer starter, our &lt;code&gt;schema.js&lt;/code&gt; looks like so in the snippet below with imports of several other module documents. You can view the schema code for each module &lt;a href="https://github.com/commercelayer/sanity-template-commercelayer/tree/main/studio/schemas"&gt;here&lt;/a&gt; in the GitHub repository.&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;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="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="c1"&gt;// We import object and document schemas&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;product&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;./product&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;country&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;./country&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;variant&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;./variant&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;size&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;./size&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;taxon&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;./taxon&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;taxonomy&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;./taxonomy&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;catalog&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;./catalog&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;blockContent&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;./blockContent&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;productImage&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;./productImage&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;localeString&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;./locale/String&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;localeText&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;./locale/Text&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;localeSlug&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;./locale/Slug&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;localeBlockContent&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;./locale/BlockContent&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="nx"&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="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="c1"&gt;// The following are document types which will appear&lt;/span&gt;
    &lt;span class="c1"&gt;// in the studio.&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;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;taxon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;taxonomy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;catalog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// When added to this list, object types can be used as&lt;/span&gt;
    &lt;span class="c1"&gt;// { type: "typename" } in other document schemas&lt;/span&gt;
    &lt;span class="nx"&gt;productImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;blockContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;localeString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;localeText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;localeSlug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;localeBlockContent&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;h3&gt;
  
  
  3️⃣  Add content to Sanity studio
&lt;/h3&gt;

&lt;p&gt;If you are working on a new project like we did when we began developing the starter, you will have to manually add content to your project using the Sanity studio running on &lt;code&gt;[localhost:3333](http://localhost:3333)&lt;/code&gt;. The studio should now have the content fields populated with the configured content schemas in the “Desk” view. You can use that to add content to your project, as seen in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EJluFtNP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682643887/tL_1yhMVy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EJluFtNP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682643887/tL_1yhMVy.jpg" alt="sanity-studio-desk-view-screenshot" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are starting a new project using a starter or a previously saved project, then you can easily import a dataset with saved data following the steps below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extract the &lt;code&gt;production.tar.gz&lt;/code&gt; file in &lt;code&gt;/.sanity-template/data&lt;/code&gt; directory using the command below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xf&lt;/span&gt; production.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extracted folder name should look like &lt;code&gt;production-export-2021-02-26t14-15-56-557z&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the command below in &lt;code&gt;/studio&lt;/code&gt; to import the &lt;code&gt;data.ndjson&lt;/code&gt; file in the extracted folder.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sanity dataset import ../.sanity-template/data/&amp;lt;name of extracted folder&amp;gt;/data.ndjson &amp;lt;your_dataset&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should check the running Sanity studio now to preview the imported content.&lt;/p&gt;

&lt;h3&gt;
  
  
  4️⃣  Add frontend and integrate with Sanity
&lt;/h3&gt;

&lt;p&gt;Before you add all frontend code to the root directory, you should move the Sanity studio code into a directory named &lt;code&gt;/studio&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jJURBNjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682680953/Gf7puWQ7B.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jJURBNjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682680953/Gf7puWQ7B.jpg" alt="sanity-starter-github-repo-studio-folder-screenshot" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this stage, you will add the frontend code of your project, which can either be a blog, marketing website, CRM, or storefront. The major thing to do here is to use any of the &lt;a href="https://www.sanity.io/docs/client-libraries"&gt;Sanity client&lt;/a&gt; libraries to integrate Sanity into your frontend and fetch data. In our case, we used the official &lt;a href="https://www.sanity.io/docs/js-client"&gt;Javascript client&lt;/a&gt; that works in Node.js and modern browsers.&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;import&lt;/span&gt; &lt;span class="nx"&gt;sanityClient&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;@sanity/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sanityClient&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;SANITY_PROJECT_ID&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;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;SANITY_DATASET&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;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="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// `false` if you want to ensure fresh data&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s an example of how we query Sanity to fetch the country and product data:&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;import&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;SanityCountry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;SanityProduct&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./typings&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;//Countries&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sanityAllCountries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parseLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lowercase&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`*[_type == "country"]{
    name,
    code,
    marketId,
    defaultLocale,
    "image": {
      "url": image.asset-&amp;gt;url
    },
    'catalog': {
      'id': catalog-&amp;gt;_id
    }
  } | order(name["&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"] asc)`&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countries&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SanityCountry&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;countries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;localization&lt;/span&gt; &lt;span class="o"&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="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;localization&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;//Products&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sanityGetProduct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parseLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lowercase&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`*[_type == "product" &amp;amp;&amp;amp; slug["&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"].current == "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"]{
    name,
    description,
    reference,
    slug,
    'images': images[]-&amp;gt;{
      'url': images.asset-&amp;gt;url
    },
    'variants': variants[]-&amp;gt;{
      label,
      code,
      name,
      size-&amp;gt;,
      'images': images[]-&amp;gt;{
        'url': images.asset-&amp;gt;url
      }
    }    
  }`&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&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;return&lt;/span&gt; &lt;span class="nx"&gt;parsingProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;lang&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 can explore all our queries for the Commerce Layer starter project &lt;a href="https://github.com/commercelayer/sanity-template-commercelayer/blob/main/utils/sanity/api.ts"&gt;here&lt;/a&gt; in the GitHub repository. Also, here’s the &lt;a href="https://github.com/commercelayer/sanity-template-commercelayer/blob/main/pages/%5BcountryCode%5D/%5Blang%5D/%5Bproduct%5D.tsx"&gt;major code&lt;/a&gt; powering our frontend alongside some hooks, utils, components, and dependencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i-0IqbHF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682886239/Z6Fxba_BQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i-0IqbHF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682886239/Z6Fxba_BQ.png" alt="" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have a Sanity Starter set up, we’ll show you the foundation principles needed to integrate commerce data from Commerce Layer. This is where you will begin to see the powerful combination of Commerce Layer data with Sanity content. And by the end of the tutorial, you will see not only the benefits of this integration, but you will also be able to experiment with your commerce data next to Sanity to see the power of both tools together.&lt;/p&gt;

&lt;h3&gt;
  
  
  5️⃣  Get Commerce Layer API Credentials
&lt;/h3&gt;

&lt;p&gt;In the starter we built, transactional functionalities of your ecommerce platform are managed by Commerce Layer, while the content is managed by Sanity studio. This will result in better order management and content management. To get started with using Commerce Layer, you will need to create an organization, perform some configurations and settings for your business, seed some demo data, and get your API credentials. The API credentials will allow you to interact with Commerce Layer in your presentation layer (frontend) and the CLI. To get the required credentials, kindly follow the steps below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a free developer account &lt;a href="https://dashboard.commercelayer.io/sign_up"&gt;here&lt;/a&gt;. If you already have an account, kindly skip to Step 3.&lt;/li&gt;
&lt;li&gt;Upon successful sign-up, skip the onboarding tutorial for the purposes of this article (we'll set up and seed the organization manually through the CLI shortly).&lt;/li&gt;
&lt;li&gt;Create a new &lt;a href="https://commercelayer.io/docs/data-model/users-and-organizations"&gt;organization&lt;/a&gt; for your business.&lt;/li&gt;
&lt;li&gt;In the Commerce Layer dashboard, click on the &lt;strong&gt;Sales channels&lt;/strong&gt; tab and create an application, with the name: &lt;code&gt;Website&lt;/code&gt;. Upon successful creation, you'll get a &lt;code&gt;CLIENT ID&lt;/code&gt; , &lt;code&gt;BASE ENDPOINT&lt;/code&gt;, and &lt;code&gt;ALLOWED SCOPES&lt;/code&gt;. Kindly remember to save that as we'll use it to interact with our application later.&lt;/li&gt;
&lt;li&gt;In the Commerce Layer dashboard, click on the &lt;strong&gt;Integrations&lt;/strong&gt; tab and create an application, with the name: &lt;code&gt;CLI&lt;/code&gt; and role: &lt;code&gt;Admin&lt;/code&gt;. Upon successful creation, you'll get a &lt;code&gt;CLIENT ID&lt;/code&gt;, &lt;code&gt;CLIENT SECRET&lt;/code&gt;, and &lt;code&gt;BASE ENDPOINT&lt;/code&gt;. Kindly remember to save that as we'll use it to interact with the CLI later.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  6️⃣  Seed Organization with Test Data
&lt;/h3&gt;

&lt;p&gt;The official &lt;a href="https://github.com/commercelayer/commercelayer-cli"&gt;Commerce Layer CLI&lt;/a&gt; helps you to manage your Commerce Layer applications right from the terminal. Installing the CLI provides access to the &lt;code&gt;commercelayer&lt;/code&gt; command. You can set it up using the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the CLI using your favorite package manager:
&lt;/li&gt;
&lt;/ul&gt;

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

//yarn
yarn global add @commercelayer/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Log into your application via the CLI using the previously created &lt;a href="https://docs.commercelayer.io/developers/roles-and-permissions#integration"&gt;integration&lt;/a&gt; application credentials like so:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commercelayer applications:login &lt;span class="nt"&gt;-o&lt;/span&gt; &amp;lt;organizationSlug&amp;gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &amp;lt;clientId&amp;gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &amp;lt;clientSecret&amp;gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &amp;lt;applicationAlias&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, with the steps below, you can use the CLI to import three demo &lt;a href="https://data.commercelayer.app/seed/markets.json"&gt;markets&lt;/a&gt; (UK, USA, and Europe), a set of &lt;a href="https://data.commercelayer.app/seed/skus.json"&gt;product SKUs&lt;/a&gt;, related &lt;a href="https://data.commercelayer.app/seed/price_lists.json"&gt;price lists&lt;/a&gt;, related &lt;a href="https://data.commercelayer.app/seed/prices.json"&gt;prices&lt;/a&gt;, &lt;a href="https://data.commercelayer.app/seed/stock_locations.json"&gt;stock locations&lt;/a&gt;, and &lt;a href="https://data.commercelayer.app/seed/stock_items.json"&gt;inventory&lt;/a&gt; into your organization using the multi_market &lt;a href="https://commercelayer.io/docs/data-model/markets-and-business-models"&gt;business model&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the &lt;a href="https://github.com/commercelayer/commercelayer-cli-plugin-seeder"&gt;seeder plugin&lt;/a&gt; using the command below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commercelayer plugins:install seeder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Seed your organization using the command below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commercelayer seed &lt;span class="nt"&gt;-b&lt;/span&gt; multi_market
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7️⃣  Final checklist and Netlify deployment configuration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In order for a starter to be validated and used through &lt;a href="https://www.sanity.io/starters"&gt;sanity.io/starters&lt;/a&gt;, it needs to follow the project name must start with &lt;code&gt;sanity-template-&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Configure your Sanity metadata in &lt;code&gt;sanity-template.json&lt;/code&gt; and add deployment configuration for the frontend web application and Sanity studio like so:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Commerce Layer Starter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A multi-country ecommerce starter built with Sanity Studio, Commerce Layer, Next.js, and deployed to Netlify."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"previewMedia"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".sanity-template/assets/preview.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"alt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Preview image with Commerce Layer, Nextjs, and Netlify's logo"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nextjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Next.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://nextjs.org"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commercelayer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Commerce Layer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://commercelayer.io"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"netlify"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Netlify"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://netlify.com"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deployment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"netlify"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sites"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"studio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"studio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Commerce Layer Starter Studio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A multi-country ecommerce starter built with Sanity Studio, Commerce Layer, Next.js, and deployed to Netlify."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./studio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"previewMedia"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".sanity-template/assets/studio.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"alt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A preview image of the Sanity studio."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"buildSettings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"studio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"dir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/dist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"cmd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Commerce Layer Starter Web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A multi-country ecommerce starter built with Sanity Studio, Commerce Layer, Next.js, and deployed to Netlify."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"previewMedia"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".sanity-template/assets/preview.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"alt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A preview image of the web demo."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"buildSettings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"dir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/out"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"cmd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The metadata information is primarily displayed on &lt;a href="https://www.sanity.io/blog/a-new-way-to-get-started-with-a-sanity-powered-website"&gt;sanity.io/create&lt;/a&gt; as described below by the visual explainer from &lt;a href="https://www.sanity.io/docs/starter-templates"&gt;Sanity docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WHILj1AG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682937904/QVBgRYBAv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WHILj1AG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1649682937904/QVBgRYBAv.png" alt="" width="720" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test your &lt;code&gt;sanity-template.json&lt;/code&gt; file for errors using the sanity-template command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sanity-template check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Build your project with the configuration in &lt;code&gt;sanity-template.json&lt;/code&gt; using the command*&lt;em&gt;:&lt;/em&gt;*
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sanity-template build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You need to refactor your project's &lt;code&gt;name&lt;/code&gt;,  &lt;code&gt;projectId&lt;/code&gt; and &lt;code&gt;dataset&lt;/code&gt; in &lt;code&gt;studio/sanity.json&lt;/code&gt; to a dynamic variable so when a user installs your starter via &lt;a href="https://www.sanity.io/starters"&gt;sanity.io/starters&lt;/a&gt;, Sanity can populate it with new values. To this, you pass the string value in &lt;code&gt;&amp;lt;#&amp;lt; ... &amp;gt;#&amp;gt;&lt;/code&gt; as seen in the snippet below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"project"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;#&amp;lt; sanity.projectTitle &amp;gt;#&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"basePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"projectId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;#&amp;lt; sanity.projectId &amp;gt;#&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dataset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;#&amp;lt; sanity.dataset &amp;gt;#&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You can also set up &lt;a href="https://github.com/renovatebot/renovate"&gt;Renovatebot&lt;/a&gt; to automatically make and merge pull requests that bump the Sanity dependencies upgrades in &lt;code&gt;studio/package.json&lt;/code&gt;. All you need to do is add a &lt;code&gt;renovate.json&lt;/code&gt; to the root directory, with the following configuration:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"github&amp;gt;sanity-io/renovate-presets:sanity-template"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run the command below to build the studio to a static bundle and deploy it to Sanity cloud on a &lt;code&gt;&amp;lt;your-project&amp;gt;.sanity.studio&lt;/code&gt; URL. You can also deploy anytime you make any change to your studio.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sanity deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PS: You can still host a studio on any cloud platform you choose too (here’s &lt;a href="https://github.com/BolajiAyodeji/cl-jamstack-ecommerce-workshop#continous-deployment-on-netlify"&gt;how to deploy to Netlify&lt;/a&gt;) so you don't have to manually deploy after every change.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lastly, push your finished code to GitHub and test it live by ****deploying the starter on Sanity following the starter specification:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.sanity.io/create?template=[githubhandle]/sanity-template-[starter-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Now that you have built a Sanity starter and integrated Commerce Layer, you can start to add more items and product data stored in Commerce Layer so you can see how your products and prices show up within your content. The power of Commerce Layer is that you can really localize your commerce data to make it work for multiple markets, all of which likely have different prices, SKUs, promotions, and even simple things like item weights and measurements. Commerce Layer gives you tremendous flexibility to sell your products locally and paired with a powerful tool like Sanity, you will be on your way to building the best, most optimized shopping experience for your customers.&lt;/p&gt;

&lt;p&gt;You can get started with the Commerce Layer starter by visiting &lt;a href="https://www.sanity.io/create?template=commercelayer/sanity-template-commercelayer"&gt;this link&lt;/a&gt;, creating a new project and following the instructions in the link. Feel free to join the &lt;a href="https://slack.commercelayer.app"&gt;Commerce Layer Slack&lt;/a&gt; community to share what you are able to build after reading this tutorial or &lt;a href="https://community.sanity.tools/desk/contribution.starter%2Ctemplate%3Dcontribution.starter;WzXQvbBRsm9g2XBDjGSTY%2Ctemplate%3Dcontribution.starter"&gt;showcase the starter on Sanity&lt;/a&gt;. For further knowledge, you can &lt;a href="https://www.sanity.io/docs/starter-templates"&gt;learn the central concepts&lt;/a&gt; needed to create a 1-click Sanity Starter, learn &lt;a href="https://github.com/BolajiAyodeji/cl-jamstack-ecommerce-workshop"&gt;how to build headless commerce web experiences&lt;/a&gt; with Commerce Layer, or learn how to &lt;a href="https://commercelayer.io/blog/how-to-sell-internationally-with-a-single-shopify-store-and-commerce-layer"&gt;sell internationally with a single Shopify store and Commerce Layer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading! 🖤&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Connect Google Colab to a Local Runtime</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Sun, 10 Apr 2022 01:56:55 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/how-to-connect-google-colab-to-a-local-runtime-2j72</link>
      <guid>https://dev.to/bolajiayodeji/how-to-connect-google-colab-to-a-local-runtime-2j72</guid>
      <description>&lt;p&gt;&lt;a href="https://research.google.com/colaboratory" rel="noopener noreferrer"&gt;Google Colaboratory&lt;/a&gt; lets you build "Colab notebooks" on the browser by blending Python executable code with rich text (along with images, HTML, and LaTeX). It is one of the simplest ways to work with Python notebooks, with no configuration required, easy collaboration, and free access to GPUs and TPUs. Unfortunately, while Colab provides access to GPUs, these resources are limited and will eventually run out. For a monthly fee, you can upgrade to Colab Pro or Colab Pro+, which gives you access to more GPUs and memory resources. However, if you're running a minimal collaboratory notebook, you can utilize the alternative option; connecting Google Colab to a local Jupyter runtime to use your local CPU and file storage.  In this article, I'll show you how to set up a Jupyter notebook and everything you need to know about connecting to Colab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646425263173%2FyJN81MlZt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646425263173%2FyJN81MlZt.png" alt="Screenshot of the TF Hub for TF2: Retraining an image classifier notebook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of the command-line interface.&lt;/li&gt;
&lt;li&gt;A working computer with Python installed.&lt;/li&gt;
&lt;li&gt;A notebook created on a registered Google Colab account.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step One
&lt;/h2&gt;

&lt;p&gt;The first step is to install Jupyter notebook. I recommend you &lt;a href="https://www.anaconda.com/download" rel="noopener noreferrer"&gt;download and install Anaconda&lt;/a&gt; for your operating system of choice. This will also install  Python, Jupyter Notebook, and other regularly used data engineering packages. Once Anaconda is installed, you automatically have Jupyter installed.&lt;/p&gt;

&lt;p&gt;Alternatively, you can install Jupyter using PIP provided you have Python installed already using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
pip3 &lt;span class="nb"&gt;install &lt;/span&gt;jupyter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon a successful installation, you can launch Anaconda and start a Jupyter server using the GUI or use the command line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two
&lt;/h2&gt;

&lt;p&gt;Install the Colab &lt;a href="https://github.com/googlecolab/jupyter_http_over_ws" rel="noopener noreferrer"&gt;Jupyter HTTP-over-WebSocket extension&lt;/a&gt; that allows you to run Jupyter notebooks using a WebSocket to proxy HTTP traffic. You can achieve that using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; jupyter_http_over_ws&amp;gt;&lt;span class="o"&gt;=&lt;/span&gt;0.0.7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, enable the extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jupyter serverextension &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--py&lt;/span&gt; jupyter_http_over_ws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Three
&lt;/h2&gt;

&lt;p&gt;Start a new Jupyter server on port 8888, allowing origin to the Colab domain using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jupyter notebook \
  --NotebookApp.allow_origin='https://colab.research.google.com' \
  --port=8888 \
  --NotebookApp.port_retries=0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the server has started, it will print a backend URL alongside a token for authentication. Kindly copy the entire URL that starts with &lt;code&gt;http://localhost&lt;/code&gt; ahead for the next step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427011253%2F8qqF8u0yf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427011253%2F8qqF8u0yf.png" alt="Screenshot 2022-03-04 at 9.48.57 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Four
&lt;/h2&gt;

&lt;p&gt;In your Google Colab notebook, click on the toggle button at the top right corner showing the RAM and Disk status bar and select the option "Connect a local runtime" as seen in the screenshots below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427242729%2FKW6E7e2im.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427242729%2FKW6E7e2im.png" alt="Screenshot 2022-03-04 at 9.53.19 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427296804%2FeiRB1Ul3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427296804%2FeiRB1Ul3b.png" alt="Screenshot 2022-03-04 at 9.54.21 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll then be asked to enter the backend URL you copied earlier. Enter it and click on the "Connect" button. Now you should be connected successfully to your local machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427893409%2FE2SeikYOv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427893409%2FE2SeikYOv.png" alt="Screenshot 2022-03-04 at 10.04.31 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427507956%2FGwMEBGDm-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1646427507956%2FGwMEBGDm-.png" alt="Screenshot 2022-03-04 at 9.57.49 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;If you're running your own personal notebook, you can as well run them locally using Jupyter notebook. However, suppose you're working on a collaborative notebook or want to take advantage of additional Google Colab features like mounting your Google drive directly into the notebook. In that case, the local runtime setup can be useful when your GPU usage reaches its limit. To avoid security issues, make sure you trust the notebook before connecting locally.&lt;/p&gt;

&lt;p&gt;I hope you found this helpful; cheers! 💙&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>programming</category>
      <category>jupyter</category>
    </item>
    <item>
      <title>How to Make any Website Shoppable with Commerce Layer</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Wed, 16 Feb 2022 13:29:03 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/how-to-make-any-website-shoppable-with-commerce-layer-3j0j</link>
      <guid>https://dev.to/bolajiayodeji/how-to-make-any-website-shoppable-with-commerce-layer-3j0j</guid>
      <description>&lt;p&gt;Digital commerce has changed, and there is an increasing demand for faster and highly efficient solutions across multiple interaction channels. The rise of &lt;a href="https://commercelayer.io/docs/core-concepts/headless-commerce" rel="noopener noreferrer"&gt;headless commerce&lt;/a&gt; allows for more creative flexibility, better performance, and efficient software development. Developers can now make any website shoppable, serve customers on several platforms using the same code and content with no interruption to the customer journey using tools like &lt;a href="https://commercelayer.io" rel="noopener noreferrer"&gt;Commerce Layer&lt;/a&gt;. As an API-first and stack agnostic platform, Commerce Layer provides commerce APIs for inventory, orders, shopping carts, prices, promotions, shipments, customers, and more. Ecommerce businesses can integrate Commerce Layer to manage the transactional part of their sales channel alongside any architecture or tool of their choice (be it WordPress, Drupal, Headless... anything!) and serve their storefront on multiple presentation layers (desktop, mobile, wearable devices, IoT, etc.).&lt;/p&gt;

&lt;p&gt;In this article, you'll practice the basics of headless commerce by building a simple &lt;a href="https://headless-swag-store.netlify.app" rel="noopener noreferrer"&gt;ecommerce product page&lt;/a&gt; with static content, HTML5, and TailwindCSS as seen in the screenshot below. We will then integrate Commerce Layer to make the website shoppable using the &lt;a href="https://github.com/commercelayer/commercelayer-js-dropin" rel="noopener noreferrer"&gt;Drop-in Javascript library&lt;/a&gt; and deploy the application to the cloud. The Drop-in library is a minimal way to get started with headless commerce and Commerce Layer, but if you're building for your business you can opt for a deeper integration using the &lt;a href="https://github.com/commercelayer/commercelayer-sdk" rel="noopener noreferrer"&gt;Commerce Layer SDK&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978483946%2F-x5owL926.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978483946%2F-x5owL926.png" alt="A screenshot of the Demo application."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Some HTML, CSS, Javascript, and command-line knowledge.&lt;/li&gt;
&lt;li&gt;A general understanding of how APIs work.&lt;/li&gt;
&lt;li&gt;An IDE and Git installed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Commerce Layer?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://commercelayer.io/" rel="noopener noreferrer"&gt;Commerce Layer&lt;/a&gt; is a multi-market commerce API and order management system that lets you add global shopping capabilities to any website, mobile app, chatbot, wearable device, or IoT device, with ease. You can compose your stack with the best-of-breed tools you want and make any experience shoppable, anywhere, through a blazing-fast, enterprise-grade, and secure API.&lt;/p&gt;

&lt;p&gt;The diagram below shows the relationships in an example stack for building a solid ecommerce web application using Commerce Layer and other &lt;a href="https://commercelayer.io/docs/core-concepts/composable-commerce" rel="noopener noreferrer"&gt;composable&lt;/a&gt; tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FBolajiAyodeji%2Fcl-jamstack-ecommerce-workshop%2Fraw%2Fmaster%2Fassets%2Farchitecture-flow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FBolajiAyodeji%2Fcl-jamstack-ecommerce-workshop%2Fraw%2Fmaster%2Fassets%2Farchitecture-flow.png" alt="https://github.com/BolajiAyodeji/cl-jamstack-ecommerce-workshop/raw/master/assets/architecture-flow.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Let's start by building the static website with HTML and TailwindCSS, all in a single &lt;code&gt;index.html&lt;/code&gt; file. We will then integrate Commerce Layer using the Dropin library!&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Create the required files
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a new folder somewhere on your computer.&lt;/li&gt;
&lt;li&gt;Create an &lt;code&gt;index.html&lt;/code&gt; file in the root directory.&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;/css&lt;/code&gt; directory with a &lt;code&gt;custom.css&lt;/code&gt; file in it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2️⃣ Get your API Credentials
&lt;/h3&gt;

&lt;p&gt;You can create an account to get access to and integrate with Commerce Layer APIs following the steps below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a free developer account &lt;a href="https://dashboard.commercelayer.io/sign_up" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If you already have an account, kindly skip to Step 3.&lt;/li&gt;
&lt;li&gt;Upon successful sign-up, skip the onboarding tutorial for the purposes of this article (we'll set up and seed the organization manually through the CLI shortly).&lt;/li&gt;
&lt;li&gt;Create a new &lt;a href="https://commercelayer.io/docs/data-model/users-and-organizations" rel="noopener noreferrer"&gt;organization&lt;/a&gt; for your business.&lt;/li&gt;
&lt;li&gt;In the Commerce Layer dashboard, click on the &lt;strong&gt;Sales channels&lt;/strong&gt; tab and create an application, with the name: &lt;code&gt;Website&lt;/code&gt;. Upon successful creation, you'll get a &lt;code&gt;CLIENT ID&lt;/code&gt; and &lt;code&gt;BASE ENDPOINT&lt;/code&gt;. Kindly remember to save that as we'll use it to interact with our application later.&lt;/li&gt;
&lt;li&gt;In the Commerce Layer dashboard, click on the &lt;strong&gt;Integrations&lt;/strong&gt; tab and create an application, with the name: &lt;code&gt;CLI&lt;/code&gt; and role: &lt;code&gt;Admin&lt;/code&gt;. Upon successful creation, you'll get a &lt;code&gt;CLIENT ID&lt;/code&gt;, &lt;code&gt;CLIENT SECRET&lt;/code&gt;, and &lt;code&gt;BASE ENDPOINT&lt;/code&gt;. Kindly remember to save that as we'll use it to interact with the CLI later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978604540%2F5h0uXQ-i_.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978604540%2F5h0uXQ-i_.jpeg" alt="screenshot-sales-channel-website.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978627048%2F7cA7BWS2_.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978627048%2F7cA7BWS2_.jpeg" alt="screenshot-integration-CLI.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ Setup Commerce Layer CLI
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/commercelayer/commercelayer-cli" rel="noopener noreferrer"&gt;Commerce Layer CLI&lt;/a&gt; helps you to manage your Commerce Layer applications right from the terminal. Installing the CLI provides access to the &lt;code&gt;commercelayer&lt;/code&gt; command. You can set it up using the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the CLI using your favorite package manager:
&lt;/li&gt;
&lt;/ul&gt;

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

//yarn
yarn global add @commercelayer/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Log into your application via the CLI using the previously created CLI credentials like so:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commercelayer applications:login &lt;span class="nt"&gt;-o&lt;/span&gt; &amp;lt;organizationSlug&amp;gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &amp;lt;clientId&amp;gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &amp;lt;clientSecret&amp;gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &amp;lt;applicationAlias&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will do the above for both applications (sales_channel and integration). The login command adds the application and sets it as the current one in session. You should log into the &lt;code&gt;sales_channel&lt;/code&gt; first, and then the &lt;code&gt;integration&lt;/code&gt;. This way, you'll have the integration as the current app (which is required by the seeder).&lt;/p&gt;

&lt;h3&gt;
  
  
  4️⃣ Seed organization with test data
&lt;/h3&gt;

&lt;p&gt;As we mentioned earlier, you can seed your organization with a merchant, a set of markets, products (SKUs), related prices, shipping methods, inventory, etc. via the CLI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the &lt;a href="https://github.com/commercelayer/commercelayer-cli-plugin-seeder" rel="noopener noreferrer"&gt;seeder plugin&lt;/a&gt; using the command below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commercelayer plugins:install seeder

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Seed your organization using the command below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commercelayer seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI will use Commerce Layer's &lt;a href="https://data.commercelayer.app/seeder" rel="noopener noreferrer"&gt;default seed data&lt;/a&gt; to populate your organization with a set of products (SKUs), related prices, and inventory information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the Static Product Page
&lt;/h2&gt;

&lt;p&gt;Now let's build our product page in a single &lt;code&gt;index.html&lt;/code&gt; file which will contain the markup for product details, prices, available variants, available quantity, item availability, shopping bag, and checkout. You can find the full code on &lt;a href="https://github.com/commercelayer/headless-swag-store/blob/main/index.html" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. In this tutorial, we will only highlight the important HTML elements and related data attributes we need for dynamic data. We will replace all style classes with the dummy content &lt;code&gt;[...]&lt;/code&gt; so you can focus on the utility classes required to interact with the Drop-in library.&lt;/p&gt;

&lt;p&gt;We will be using some &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes" rel="noopener noreferrer"&gt;data attributes&lt;/a&gt; to store extra information that doesn't have any visual representation like &lt;code&gt;data-sku-code&lt;/code&gt; to store the SKU code of an item or &lt;code&gt;data-add-to-bag-id&lt;/code&gt; to add a selected variant to the shopping bag when the "Add to bag" button is clicked. The Dropin library requires some data attributes to add dynamic data to a static web page. With this mechanism, you're building ecommerce with almost no code required (just HTML tags). Now let's proceed!&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Create Static Content
&lt;/h3&gt;

&lt;p&gt;You should add some content to the page, such as product names, descriptions, reviews and images, and more. This content can be created with any CMS and rendered with any language. For this tutorial we're using just plain HTML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Headless Swag Store&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css"&lt;/span&gt;
          &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
        &lt;span class="nt"&gt;/&amp;gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-10"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center justify-between"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-indigo-600 font-medium"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    Choose a size
                  &lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-4 flex -mx-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-1 px-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt;
                      &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"variant"&lt;/span&gt;
                      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant-select block appearance-none border-2 border-gray-500 text-base-700 py-3 px-4 pr-8 rounded"&lt;/span&gt;
                      &lt;span class="na"&gt;data-sku-reference=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000"&lt;/span&gt;
                      &lt;span class="na"&gt;data-price-container-id=&lt;/span&gt;&lt;span class="s"&gt;"price"&lt;/span&gt;
                      &lt;span class="na"&gt;data-availability-message-container-id=&lt;/span&gt;&lt;span class="s"&gt;"availability-message"&lt;/span&gt;
                      &lt;span class="na"&gt;data-add-to-bag-id=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag"&lt;/span&gt;
                      &lt;span class="na"&gt;data-add-to-bag-quantity-id=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag-quantity"&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt; &lt;span class="na"&gt;selected&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Select variant&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
                        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000SXXX"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (S)"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        Small
                      &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
                        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000MXXX"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (M)"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        Medium
                      &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
                        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000LXXX"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (L)"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        Large
                      &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
                        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000XLXX"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (XL)"&lt;/span&gt;
                        &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        Extra Large
                      &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                  &lt;span class="c"&gt;&amp;lt;!-- Add to bag quantity --&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-1 px-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag-quantity"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sr-only"&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Add to bag quantity&lt;span class="nt"&gt;&amp;lt;/label&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
                      &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag-quantity"&lt;/span&gt;
                      &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;
                      &lt;span class="na"&gt;min=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
                      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-add-to-bag-quantity block appearance-none border-2 border-gray-500 text-base-700 py-3 px-4 pr-2 rounded"&lt;/span&gt;
                    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
          &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"icon"&lt;/span&gt;
          &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://data.commercelayer.app/assets/images/favicons/favicon.ico"&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;   
     &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Image gallery --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-6 max-w-2xl mx-auto sm:px-6 lg:max-w-7xl lg:px-8 lg:grid lg:grid-cols-3 lg:gap-x-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hidden aspect-w-3 aspect-h-4 rounded-lg overflow-hidden lg:block"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
               &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/img/01.png"&lt;/span&gt;
               &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Model wearing the gray men hoodie"&lt;/span&gt;
               &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full h-full object-center object-cover"&lt;/span&gt;
               &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hidden lg:grid lg:grid-cols-1 lg:gap-y-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"aspect-w-3 aspect-h-2 rounded-lg overflow-hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
                  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/img/02.png"&lt;/span&gt;
                  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"The gray men hoodie"&lt;/span&gt;
                  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full h-full object-center object-cover"&lt;/span&gt;
                  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"aspect-w-3 aspect-h-2 rounded-lg overflow-hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
                  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/img/03.png"&lt;/span&gt;
                  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"The gray men hoodie"&lt;/span&gt;
                  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full h-full object-center object-cover"&lt;/span&gt;
                  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"aspect-w-4 aspect-h-5 sm:rounded-lg sm:overflow-hidden lg:aspect-w-3 lg:aspect-h-4"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
               &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/img/04.png"&lt;/span&gt;
               &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"The gray men hoodie"&lt;/span&gt;
               &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full h-full object-center object-cover"&lt;/span&gt;
               &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Product info --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-w-2xl mx-auto pt-10 pb-8 px-4 sm:px-6 lg:max-w-7xl lg:pt-16 lg:px-8 lg:grid lg:grid-cols-3 lg:grid-rows-[auto,auto,1fr] lg:gap-x-8"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"lg:col-span-2 lg:border-r lg:border-gray-200 lg:pr-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-extrabold tracking-tight text-gray-900 sm:text-3xl"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            Sport Grey Unisex Hoodie Sweatshirt
         &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

         &lt;span class="c"&gt;&amp;lt;!-- Description and details --&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"py-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sr-only"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Description&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"space-y-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-base text-gray-900"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  This comfortable hoodie is made of 100% combed ring-spun
                  cotton except for heather black logo, which contains
                  polyester. Our premium Unisex Sport Hoodie Sweatshirt is
                  everything you could ask for: it's warm and cozy,
                  heavyweight, unique, roomy, and it's built to last. Sign up
                  for our subscription service and be the first to get new,
                  exciting colors, like our upcoming "Charcoal Gray" limited
                  release.
               &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2️⃣ Add Configuration
&lt;/h3&gt;

&lt;p&gt;Add the code below to &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; section of the &lt;code&gt;index.html&lt;/code&gt; file just before the &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; tag and add the required publishable configuration data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Config --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"clayer-config"&lt;/span&gt;
  &lt;span class="na"&gt;data-base-url=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;yourOrganizationUrl&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;data-cache=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;data-client-id=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;yourClientId&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;data-market-id=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;yourMarketId&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;data-country-code=&lt;/span&gt;&lt;span class="s"&gt;"US"&lt;/span&gt;
  &lt;span class="na"&gt;data-language-code=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;
  &lt;span class="na"&gt;data-cart-url=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;https://example.com/cart&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;data-return-url=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;https://example.com/return&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;data-privacy-url=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;https://example.com/privacy&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;data-terms-url=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;https://example.com/terms&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;data-dev-settings-debug=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;data-dev-settings-console=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;data-dev-settings-trace=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- JS Library --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script
  &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;https://cdn.jsdelivr.net/npm/@commercelayer/js-dropin@1.5.12/lib/index.js&amp;gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;clayer-config&lt;/code&gt; — stores all the data attributes with your credentials and page preferences.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-base-url&lt;/code&gt; — stores your organization base endpoint as defined on Commerce Layer (something like &lt;code&gt;https://yourdomain.commercelayer.io&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-client-id&lt;/code&gt; — stores your sales channel application's client ID.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-market-id&lt;/code&gt; stores the &lt;em&gt;number&lt;/em&gt; of the market you want to work on as defined in Commerce Layer.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-country-code&lt;/code&gt; — stores the country code of the country assigned to an order (e.g &lt;code&gt;US&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-language-code&lt;/code&gt; — stores the language assigned to an order (e.g &lt;code&gt;en-US&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-cart-url&lt;/code&gt;, &lt;code&gt;data-return-url&lt;/code&gt;, &lt;code&gt;data-privacy-url&lt;/code&gt;, &lt;code&gt;data-terms-url&lt;/code&gt; — store the links to external pages that Commerce Layer should redirect your user to upon certain requests (we don't need these for this tutorial, so we'll add some dummy links).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3️⃣ Add a Price
&lt;/h3&gt;

&lt;p&gt;Add the markup below to fetch the selling price (amount) and original price (compare-at-amount) of an SKU. You should add an element with &lt;code&gt;clayer-price&lt;/code&gt; class and &lt;code&gt;data-sku-code&lt;/code&gt; data attribute wherever you want to show a product price. The child element with class &lt;code&gt;amount&lt;/code&gt; gets populated with the price that has been defined in Commerce Layer for that SKU code (for the market defined in the configuration step above). The child element with class &lt;code&gt;compare-at-amount&lt;/code&gt; gets populated only if compare-at-amount is defined and is higher than the amount. The &lt;code&gt;price&lt;/code&gt; ID is used to match the &lt;code&gt;data-price-container-id&lt;/code&gt; in the variant options (as seen in the next section).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Price --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Product information&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-price"&lt;/span&gt;
         &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"price"&lt;/span&gt;
         &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000XLXX"&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... amount"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... compare-at-amount"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Config [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- JS Library [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4️⃣ Add Variants Selection
&lt;/h3&gt;

&lt;p&gt;If your product has many variants, add an element with &lt;code&gt;clayer-variant&lt;/code&gt; class and &lt;code&gt;data-sku-code&lt;/code&gt; data attribute for each variant option. This will fetch the SKU for each variant from Commerce Layer. You can use either a select tag or a list of radio buttons (appending the class &lt;code&gt;clayer-variant-select&lt;/code&gt; or &lt;code&gt;clayer-variant-radio&lt;/code&gt; respectively). You can also add other data attributes that will be used in the shopping bag based on a user's variant selection such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data-sku-name&lt;/code&gt; — the name of the selected SKU to be displayed in the shopping bag.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-sku-reference&lt;/code&gt; — the reference of the selected SKU to be displayed in the shopping bag.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-sku-image-url&lt;/code&gt; — the URL to an image of the SKU to be displayed in the shopping bag.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-price-container-id&lt;/code&gt; — the ID of the DOM element that contains the price for this SKU, in the current market (potentially different variants can have different prices; when selecting a new variant, the price will be updated accordingly).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-availability-message-container-id&lt;/code&gt; — the ID of the DOM element that contains the availability message for this SKU, in the current market (more on this later).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-add-to-bag-id&lt;/code&gt;: the ID of the "Add to bag" DOM element (when clicking the "Add to bag" button with the specified ID, the selected variant will be added to bag).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-add-to-bag-quantity-id&lt;/code&gt; — the ID of the "Add to bag quantity" DOM element (when clicking the "Add to bag" button with the specified ID, the selected quantity of the variant will be added to bag).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Price  [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Variants (select sizes) --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Choose a size&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-4 flex -mx-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-1 px-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt;
            &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"variant"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant-select ..."&lt;/span&gt;
            &lt;span class="na"&gt;data-sku-reference=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000"&lt;/span&gt;
            &lt;span class="na"&gt;data-price-container-id=&lt;/span&gt;&lt;span class="s"&gt;"price"&lt;/span&gt;
            &lt;span class="na"&gt;data-availability-message-container-id=&lt;/span&gt;&lt;span class="s"&gt;"availability-message"&lt;/span&gt;
            &lt;span class="na"&gt;data-add-to-bag-id=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag"&lt;/span&gt;
            &lt;span class="na"&gt;data-add-to-bag-quantity-id=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag-quantity"&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt; &lt;span class="na"&gt;selected&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Select variant&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
              &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000SXXX"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (S)"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Small
            &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
              &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000MXXX"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (M)"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Medium
            &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
              &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000LXXX"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (L)"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Large
            &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
              &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-variant"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-code=&lt;/span&gt;&lt;span class="s"&gt;"SWEETHMUB7B7B7000000XLXX"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-name=&lt;/span&gt;&lt;span class="s"&gt;"Sport Grey Unisex Hoodie Sweatshirt with Black Logo (XL)"&lt;/span&gt;
              &lt;span class="na"&gt;data-sku-image-url=&lt;/span&gt;&lt;span class="s"&gt;"https://img.commercelayer.io/skus/SWEETHMUB7B7B7000000.png?fm=jpg&amp;amp;q=90"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Extra Large
            &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="c"&gt;&amp;lt;!-- Other variant input elements [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Config [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- JS Library [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5️⃣ Add to Bag
&lt;/h3&gt;

&lt;p&gt;When an option (variant) is selected and the "Add to bag" button is clicked, the selected variant is added to the shopping bag using the &lt;code&gt;clayer-add-to-bag&lt;/code&gt; class and ID that matches the variants' &lt;code&gt;data-add-to-bag-id&lt;/code&gt;. You can also optionally add a quantity field to let the customer add more than one item to the shopping bag using the &lt;code&gt;clayer-add-to-bag-quantity&lt;/code&gt; attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Price  [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Variants (select sizes) --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Add to bag quantity --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag-quantity"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Add to bag quantity&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
              &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag-quantity"&lt;/span&gt;
              &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;
              &lt;span class="na"&gt;min=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
              &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-add-to-bag-quantity ..."&lt;/span&gt;
        &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Add to bag button --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
         &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-add-to-bag ..."&lt;/span&gt;
         &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"add-to-bag"&lt;/span&gt;
         &lt;span class="na"&gt;data-availability-message-container-id=&lt;/span&gt;&lt;span class="s"&gt;"availability-message"&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Add to bag
      &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Config [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- JS Library [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6️⃣ Add Availability Message Templates
&lt;/h3&gt;

&lt;p&gt;Add an element with &lt;code&gt;clayer-availability-message-available-template&lt;/code&gt; ID as the template tag to be displayed when the selected SKU is available. All the child elements will be populated with the delivery lead time and shipping method information related to the selected variant.&lt;/p&gt;

&lt;p&gt;Add an element with &lt;code&gt;clayer-availability-message-unavailable-template&lt;/code&gt; ID as the template tag to be displayed when the selected SKU is not available. This element will be appended to a specific container when customers will try to add an SKU to the shopping bag and that SKU’s stock item has a quantity of zero or doesn’t exist at all. If you try to create a line item, you will get an "out of stock" error. The &lt;code&gt;clayer-availability-message-unavailable-template&lt;/code&gt; is used to store an "out of stock" message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Price  [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Variants (select sizes) --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Add to bag quantity --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Availability message templates --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-availability-message-container"&lt;/span&gt;
         &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"availability-message"&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"clayer-availability-message-available-template"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            Available in
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-availability-message-available-min-days"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            -
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-availability-message-available-max-days"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            days with
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-availability-message-available-shipping-method-name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            (&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-availability-message-available-shipping-method-price"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;)
         &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"clayer-availability-message-unavailable-template"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;The selected SKU is not available.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Config [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- JS Library [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7️⃣ Add Shopping Bag Summary
&lt;/h3&gt;

&lt;p&gt;The shopping bag includes a list of all items added to the bag alongside a summary of the current shopping bag details. Add an element with &lt;code&gt;clayer-shopping-bag-container&lt;/code&gt; ID wherever you want to show the shopping bag. The &lt;code&gt;clayer-shopping-bag-items-container&lt;/code&gt; is used as the parent element of the shopping bag line items, built from the &lt;code&gt;clayer-shopping-bag-item-template&lt;/code&gt; template tag. The lists below explain what each child data attribute does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The line item template elements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-item-name&lt;/code&gt; — will be populated with the name of the SKU.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-item-unit-amount&lt;/code&gt; — displays the unit amount of the SKU.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-item-qty-container&lt;/code&gt; — displays an input field with the quantity of the SKU added to the bag (you can use this to update the quantity too).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-item-availability-message-container&lt;/code&gt; — displays an “out of stock” message (contained in &lt;code&gt;clayer-availability-message-unavailable-template&lt;/code&gt;) when you change a quantity and that quantity is not available.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-item-total-amount&lt;/code&gt; — displays the total amount of a line item.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-item-remove&lt;/code&gt; — displays a link to remove an item from the shopping bag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The order summary elements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-subtotal&lt;/code&gt; — displays the subtotal amount of the entire shopping bag.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-shipping&lt;/code&gt; — displays the shipping cost of the order.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-payment&lt;/code&gt; — displays the selected payment method charge (if any).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-discount&lt;/code&gt; — displays the discount amount of the order (if applied).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-taxes&lt;/code&gt; — displays the cost of tax (if present).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clayer-shopping-bag-total&lt;/code&gt; — displays the grand total summing up all the above costs for the order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By default, the shopping bag container is always closed. The &lt;code&gt;clayer-shopping-bag-toggle&lt;/code&gt; element toggles an open class (attached to a button) on the shopping bag container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Price  [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Variants (select sizes) --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Add to bag quantity --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Availability message templates --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Shopping bag --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Shopping bag&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         Your shopping bag contains
         &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-items-count"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
         items worth
         &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-total"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-toggle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Toggle Bag &lt;span class="ni"&gt;&amp;amp;#8645;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;thead&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  SKU
               &lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  Unit price
               &lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  Q.ty
               &lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  Total
               &lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;tbody&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-items-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-item-template"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-item-name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-item-unit-amount"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-item-qty-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
                     &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;
                     &lt;span class="na"&gt;min=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
                     &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;
                     &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt;
                     &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-item-availability-message-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-item-total-amount"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-item-remove"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;❌&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               Subtotal:
               &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-subtotal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               Shipping:
               &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-shipping"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               Payment:
               &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-payment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               Discount:
               &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-discount"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               Taxes:
               &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-taxes"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
               Total:
               &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clayer-shopping-bag-total"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Config [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- JS Library [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8️⃣ Add Checkout Button
&lt;/h3&gt;

&lt;p&gt;Add an element with &lt;code&gt;clayer-shopping-bag-checkout&lt;/code&gt; class wherever you want to show the checkout button. This button will link to a dedicated checkout page where a customer can complete their purchase and place the order. We'll explain how this works soon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Static content [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Price  [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Variants (select sizes) --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Add to bag quantity --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Availability message templates --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Shopping bag --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!--Checkout button--&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"... clayer-shopping-bag-checkout"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Proceed to checkout
      &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Config [...] --&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- JS Library [...] --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coupled together, we get a nice-looking product page with some static content and some elements updated dynamically. In summary, once a user selects a variant and clicks the "Add to bag" button, we pass the data down with help from the specified data attributes and create an order associated with some line items. If there are any errors, we display them in the availability message container. The customer can then decide to check out the order.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978689499%2FDiKqjiPMn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644978689499%2FDiKqjiPMn.jpeg" alt="headless-swag-store-demo-cart.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Checkout Functionality
&lt;/h2&gt;

&lt;p&gt;The Drop-in library uses the &lt;a href="https://github.com/commercelayer/commercelayer-react-checkout" rel="noopener noreferrer"&gt;Commerce Layer checkout application&lt;/a&gt; to provide a PCI-compliant, PSD2-compliant, and production-ready checkout flow powered by Commerce Layer APIs. The orders API will return the checkout URL using the format &lt;code&gt;&amp;lt;your organization slug&amp;gt;.checkout.commercelayer.app/:order_id?accessToken=&amp;lt;token&amp;gt;&lt;/code&gt;. The Drop-in library will then automatically pass that URL to the checkout button (with class &lt;code&gt;clayer-shopping-bag-checkout&lt;/code&gt;) alongside the order ID and required access token. When you click on the checkout button, you will be redirected to the checkout application. Upon successful checkout, the order will be sent to and can be managed in the orders management system (OMS), in the Commerce Layer dashboard. So cool, right 🙃?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://commercelayer.io/blog/introducing-our-hosted-checkout-application" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20tsvadbstik9b60am24.png" alt="A blog post cover image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the Final Project
&lt;/h2&gt;

&lt;p&gt;Now let's push our project to GitHub and deploy it to Netlify or Vercel. Whenever you push any change to GitHub, both tools will run your build and re-deploy the repository again. You can follow the guidelines in the documentation for &lt;a href="https://docs.netlify.com/site-deploys/create-deploys/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt; or &lt;a href="https://vercel.com/docs/concepts/deployments/overview" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; to get set up for either tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional resources
&lt;/h2&gt;

&lt;p&gt;An order can consist of a customer, line items (SKUs, cost of shipping method, cost of payment method, taxes, or gift cards), a billing address, a shipping address, discount(s) calculated from active promotions, redeemed gift card(s), a payment method, and a payment source type. You can &lt;a href="https://commercelayer.io/docs/data-model/anatomy-of-an-order" rel="noopener noreferrer"&gt;read this guide&lt;/a&gt; to learn more about the anatomy of an order and check out the &lt;a href="https://docs.commercelayer.io/api" rel="noopener noreferrer"&gt;Commerce Layer API reference&lt;/a&gt;. Also, check out the &lt;a href="https://commercelayer.io/docs/data-model" rel="noopener noreferrer"&gt;Commerce Layer data model&lt;/a&gt; for an overview of the most relevant API entities, their mutual relationships, and common usage (including E-R diagrams).&lt;/p&gt;

&lt;p&gt;Here are some more resources to learn about headless commerce, Commerce Layer, and data attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://commercelayer.io/why" rel="noopener noreferrer"&gt;Why Commerce Layer?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://commercelayer.io/guides/headless-commerce" rel="noopener noreferrer"&gt;Comprehensive Guide to Headless Commerce&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://commercelayer.io/docs/core-concepts" rel="noopener noreferrer"&gt;Commerce Layer Core Concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://commercelayer.io/developers" rel="noopener noreferrer"&gt;Commerce Layer Developer Resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://commercelayer.io/jamstack" rel="noopener noreferrer"&gt;Jamstack Whitepaper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes" rel="noopener noreferrer"&gt;Using data attributes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/dataset" rel="noopener noreferrer"&gt;HTMLOrForeignElement.dataset&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Yes! You have successfully turned a website into a &lt;a href="https://headless-swag-store.netlify.app/" rel="noopener noreferrer"&gt;shoppable website&lt;/a&gt; using Commerce Layer and the Drop-in Library; how cool is that?! 😃. &lt;/p&gt;

&lt;p&gt;With &lt;a href="https://commercelayer.io/" rel="noopener noreferrer"&gt;Commerce Layer&lt;/a&gt;, you can manage all transactional parts of your ecommerce business, integrate with any CMS of your choice to manage content, build your user interface/experience with your favorite technologies, and build your business logic without friction. In addition, this will result in more flexibility and autonomy between sub-teams in your engineering team, thereby helping you scale your business globally.&lt;/p&gt;

&lt;p&gt;This is a great way to quickly start building with Commerce Layer and can be used for specific use cases such as adding ecommerce to a Jamstack website or transforming a Shopify theme into a multi-market store. To create a comprehensive global shopping platform for your brand, check out our &lt;a href="https://docs.commercelayer.io" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; and &lt;a href="https://slack.commercelayer.app" rel="noopener noreferrer"&gt;join our Slack community&lt;/a&gt; to learn about the possibilities.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>ecommerce</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Fix Git Always Asking for User Credentials</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Wed, 25 Mar 2020 21:20:10 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/how-to-fix-git-always-asking-for-user-credentials-2ai2</link>
      <guid>https://dev.to/bolajiayodeji/how-to-fix-git-always-asking-for-user-credentials-2ai2</guid>
      <description>&lt;p&gt;Have you ever encountered Git asking you for your username and password every time you try to interact with GitHub even after configuring it? Well, this is a very common problem among users who use the HTTPS clone URL for their repository. In this article, I'll show you how to fix this.&lt;/p&gt;




&lt;p&gt;The &lt;code&gt;https://&lt;/code&gt; clone URLs are available on all public and private repositories. These URLs work everywhere, even if you are behind a firewall or proxy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6PHzZgsX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/bolaji/image/upload/v1570636713/null/blog/0003/01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6PHzZgsX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/bolaji/image/upload/v1570636713/null/blog/0003/01.png" alt="" width="446" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you interact with a remote repository using HTTPS URLs on the command line, you'll be asked for your GitHub username and password, this sucks right?&lt;/p&gt;

&lt;p&gt;Well using an HTTPS remote URL has some advantages: it's easier to set up than SSH :), and usually works through strict firewalls and proxies. However, it also prompts you to enter your GitHub user credentials every time you pull or push a repository :(.&lt;/p&gt;

&lt;h2&gt;
  
  
  You can fix this by configuring Git to store your password for you.
&lt;/h2&gt;




&lt;p&gt;Here's how:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the URL of origin remote using SSH instead of HTTPS;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote set-url origin git@github.com:username/repo.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Make Git store the username and password and it will never ask for them.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; credential.helper store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Save the username and password for a session (cache it);
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; credential.helper cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You can also set a timeout for the above setting
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; credential.helper &lt;span class="s1"&gt;'cache --timeout=600'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bingo, you just fixed it, Git will never ask for your credentials again.&lt;/p&gt;




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

&lt;p&gt;However, due to security reasons, it is advisable that you use SSH to interact with GitHub, especially if you work for a company or you're using a computer that isn't yours.&lt;/p&gt;

&lt;p&gt;Using the SSH protocol, you can connect to GitHub without supplying your username or password every time. Learn how to connect to GitHub with SSH &lt;a href="https://help.github.com/en/articles/connecting-to-github-with-ssh"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>cli</category>
    </item>
    <item>
      <title>Git first time setup</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Tue, 23 Jul 2019 16:20:55 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/git-first-time-setup-bnd</link>
      <guid>https://dev.to/bolajiayodeji/git-first-time-setup-bnd</guid>
      <description>&lt;p&gt;Git is a Free and Open Source Distributed Version Control System.&lt;/p&gt;

&lt;p&gt;By far, Git is the most widely used modern version control system in the world today. Git is a distributed and actively maintained open source project originally developed in 2005 by &lt;a href="https://en.wikipedia.org/wiki/Linus_Torvalds"&gt;Linus Torvalds&lt;/a&gt;, the famous creator of the Linux operating system kernel.&lt;/p&gt;

&lt;p&gt;Unlike older centralized version control systems such as SVN and CVS, Git is distributed: every developer has the full history of their code repository locally. Git also works well on a wide range of operating systems and IDEs (Integrated Development Environments).&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how to install Git, set it up for the first time, useful tips and resources to learn more/ learn advanced git concepts. Let's roll!&lt;/p&gt;




&lt;p&gt;I assume you already know what Version control is, if you don't, kindly check out this &lt;a href="http://slides.com/bolajiayodeji/introduction-to-version-control-with-git-and-github"&gt;slide&lt;/a&gt; to learn more. &lt;/p&gt;

&lt;p&gt;Here's a quick recap of what Version control means:&lt;br&gt;
Version Control is:&lt;br&gt;
the process of managing changes to source code or set of files over time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Version control is the process of managing changes to source code or set of files over time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Version control software keeps track of every modification to the code in a special kind of database.&lt;br&gt;
If a mistake is made, developers can restore and compare earlier versions of the code to help fix the mistake while minimizing disruption to all team members or contributors.&lt;/p&gt;



&lt;p&gt;Now that you know what Version Control and Git mean, let's install it.&lt;/p&gt;
&lt;h3&gt;
  
  
  For Mac OS:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://git-scm.com/download/mac"&gt;Download Git for macOS&lt;/a&gt;&lt;br&gt;
or install using &lt;a href="https://brew.sh"&gt;Homebrew&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  For Linux OS:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/download/linux"&gt;Download Git for Linux&lt;/a&gt; or &lt;br&gt;
Install for Debian-based Linux systems&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;or Install for Red Hat-based Linux systems&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo yum upgrade
sudo yum install git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  For Windows OS:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/download/win"&gt;Download Git for Windows&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Here's a more detailed installation guide for different systems on &lt;a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git"&gt;Git official docs&lt;/a&gt;
&lt;/h4&gt;
&lt;/blockquote&gt;




&lt;p&gt;Now that you have Git on your system, let's set up the Git environment. &lt;br&gt; &lt;br&gt;
Git comes with a tool called &lt;code&gt;git config&lt;/code&gt; that lets you get and set configuration variables that control all aspects of how Git looks and operates.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First set your identity, your name and email address like so:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global user.name "bolajiayodeji"
git config --global user.email mailtobolaji@gmail.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;the &lt;code&gt;--global&lt;/code&gt; option makes sure these values are used throughout your system&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next set up the default text editor you'll use whenever you need to enter a message in Git. This is not compulsory, if you don't configure this, Git will use your default editor. If you want to use something else, configure like so:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global core.editor emacs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Next, set up colors for your Git console.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For Linux OS users, you can use third pary Zsh configurators like &lt;a href="https://ohmyz.sh/"&gt;oh my zsh&lt;/a&gt; to customize your terminal look with themes :).&lt;br&gt;
To configure this, do this:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global color.ui true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The color.ui is a meta configuration that includes all the various color.* configurations available with git commands. &lt;/p&gt;

&lt;p&gt;Now Git is ready for use. &lt;/p&gt;

&lt;h2&gt;
  
  
  Check your settings
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user.name=bolajiayodeji
user.email=mailtobolaji@gmail.com
color.ui=true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;Want to learn some super Git commands? &lt;br&gt;&lt;br&gt;
I wrote an article: &lt;a href="https://www.bolajiayodeji.com/git-cheat-sheet/"&gt;Git Cheat Sheet&lt;/a&gt; that covers some important Git commands you'll need. &lt;/p&gt;

&lt;p&gt;Find more resources to learn Git &lt;a href="https://try.github.io/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Version control software is an essential part of the every-day of modern-day software developer practices. Once accustomed to the powerful benefits of version control systems, many developers wouldn’t consider working without it even for non-software projects.&lt;/p&gt;

</description>
      <category>git</category>
      <category>versioncontrol</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Introduction to Web Accessibility</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Tue, 07 May 2019 05:44:09 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/introduction-to-web-accessibility-5a7o</link>
      <guid>https://dev.to/bolajiayodeji/introduction-to-web-accessibility-5a7o</guid>
      <description>&lt;p&gt;As developers, it’s easy to assume that all users can see and use a keyboard, mouse or screen, you feel everyone can interact with your web page the same way you do. This can lead to a user experience that works well for some people but creates issues for others :(&lt;/p&gt;

&lt;p&gt;Many developers have only a little or blurred understanding of what&lt;br&gt;
accessibility means, of course, accessibility can be a complex and difficult&lt;br&gt;
topic but understanding it, its scope and its impact can make you a better and&lt;br&gt;
inclusive web developer.&lt;/p&gt;

&lt;p&gt;In this article, I’ll introduce you to accessibility, what it means, why you should care, a few tips, tools and resources to get you started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lma4sHP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AWXgUQC2V92dkcYgZ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lma4sHP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2AWXgUQC2V92dkcYgZ" alt="" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;span&gt;&lt;em&gt;Gif by &lt;a href="https://dribbble.com/jonadinges"&gt;Jona Dinges&lt;/a&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  What is Accessibility?
&lt;/h3&gt;

&lt;p&gt;Let’s start by defining accessibility and inclusion.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;According to &lt;a href="https://www.dictionary.com/browse/accessibility"&gt;thesaurus&lt;br&gt;
dictionary&lt;/a&gt;, accessibility&lt;br&gt;
simply means: easy to approach, reach, enter, speak with, or use.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Inclusion&lt;/strong&gt; is a societal ideology regarding individuals with disabilities and&lt;br&gt;
special education. I*&lt;em&gt;nclusion&lt;/em&gt;* describes a group that’s particularly welcoming&lt;br&gt;
to all kinds of people irrespective of their differences.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;blockquote&gt;
&lt;p&gt;In computer-human interaction, accessibility simply means making the web&lt;br&gt;
accessible and having functionalities that can be operated by literally everyone&lt;br&gt;
including those with all forms of disabilities, limitations and conditions...&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h4&gt;
  
  
  Those with Disabilities
&lt;/h4&gt;

&lt;p&gt;According to WHO, there are about 285,000,000 people in the world today. Blind&lt;br&gt;
and visually impaired make up of the 285,000,000 people according to the &lt;a href="http://www.who.int/mediacentre/factsheets/fs282/en/"&gt;World&lt;br&gt;
Health Organization&lt;/a&gt; (June&lt;br&gt;
2012) with 39,000,000 categorized as legally blind and the remaining 246,000,000&lt;br&gt;
visually impaired. The deaf and hearing impaired make up 275,000,000 (2004) in&lt;br&gt;
the moderate-to-profound hearing impairment category.&lt;/p&gt;

&lt;p&gt;Some forms of disabilities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Physical disabilities&lt;/strong&gt; (One that affects a person’s mobility or dexterity)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intellectual or Learning Disabilities&lt;/strong&gt; ( People with an intellectual,
learning, or cognitive disability have a reduced capacity to read, learn tasks
or process information.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual impairments&lt;/strong&gt; (People with sight challenges, visually impaired
individuals and blind people.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hearing impairments&lt;/strong&gt; ( Deafness and hearing loss)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neurological disabilities&lt;/strong&gt; ( Disabilities associated with damage to the
nervous system that results in the loss of some physical or mental functions.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Those with limitations/ conditions
&lt;/h4&gt;

&lt;p&gt;Disabilities can also be conditional. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A broken arm&lt;/li&gt;
&lt;li&gt;A loud restaurant&lt;/li&gt;
&lt;li&gt;Not speaking the local language e.t.c&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these are examples where someone may benefit from accessible practices.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Everybody is a keyboard user when they are eating with their mouse hand.&lt;/p&gt;

&lt;p&gt;— Adrian Roselli&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  How can we help these people?
&lt;/h4&gt;

&lt;p&gt;Web Accessibility comes to the rescue. It is a practice whereby web applications&lt;br&gt;
are designed and developed so that its functionality can be operated by people&lt;br&gt;
with disabilities. &lt;/p&gt;


&lt;h3&gt;
  
  
  Web Accessibility Guidelines
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Throughout this article, I’ll refer to the &lt;a href="https://www.w3.org/TR/WCAG20/"&gt;Web Content Accessibility Guidelines&lt;br&gt;
(WCAG) 2.0&lt;/a&gt;, a set of guidelines and best&lt;br&gt;
practices put together by web accessibility experts to address what&lt;br&gt;
“accessibility” means in a methodical way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;WCAG is organized around four principles often called &lt;em&gt;The POUR Principle&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Perceivable&lt;/strong&gt; 
Can users perceive the content? This ensures that our
applications are perceivable with &lt;em&gt;sight, touch or hearing&lt;/em&gt; senses via the
browser or assistive technologies e.g Screen readers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operable&lt;/strong&gt; 
Can users use UI components easily and navigate the content? For
example, something that requires a hover interaction cannot be operated by
someone who can’t use a mouse or touch screen. This means users should be able
to control your web apps elements using either the mouse, keyboard or an
assistive device.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understandable&lt;/strong&gt; 
Can users understand the content? Can users understand the
interface and is it clear and concise? This ensures an easy understanding and
smooth user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robust&lt;/strong&gt; 
Can the content be consumed by a wide variety of users on several
browsers? This ensures compatibility of your app across several devices,
browsers or operating systems.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Web accessibility tips
&lt;/h3&gt;

&lt;p&gt;Now that you understand what Web Accessibility means and why you should care,&lt;br&gt;
let me walk you through a few tips that would help you to build accessible&lt;br&gt;
websites :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Always add alternative texts to images&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one thing most developers miss, I used to miss this too when I started&lt;br&gt;
out because I didn’t really understand the essence of &lt;em&gt;alternative texts.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Alternative texts (also known as &lt;code&gt;alt&lt;/code&gt;) is a word that can be inserted as an attribute in an HTML document to tell your website, users, the contents of an image. The alt text appears in a blank box that would normally contain the image. Alt text is useful when an image is not available because of a broken link, changed URL or something else.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Alternative texts as the name imply serve as an alternative for screen readers.&lt;br&gt;
They are read aloud to blind users on a screen reader and other screens&lt;br&gt;
assistive technologies.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You add alternative texts to images with the &lt;em&gt;&lt;code&gt;alt&lt;/code&gt;&lt;/em&gt; attribute&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./school.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"a private school in Kogi State."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another important aspect of the &lt;code&gt;alt&lt;/code&gt; attribute is that you should be specific&lt;br&gt;
when adding these texts. For example, examine the images below:&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LlMaHYtB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/600/0%2Al82N_5g3MF01TecN.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LlMaHYtB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/600/0%2Al82N_5g3MF01TecN.jpg" alt="" width="600" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;Beautiful &lt;a href="https://medium.com/u/61b12cb51464"&gt;Aniekan Inyang&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./lady.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"a beautiful lady"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;--&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./lady.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"a beautiful lady smiling in front of a brown door"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Which of the code above would support accessibility more, 1 or 2?&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ksGFb70w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVwaIywCKRAu6d8M74gkQVg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ksGFb70w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AVwaIywCKRAu6d8M74gkQVg.jpeg" alt="" width="640" height="640"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./dog.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"a cute dog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;--&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./dog.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"a cute dog sitting beside a pillow on a gray couch"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Which of the code above would support accessibility more, 1 or 2?&lt;/p&gt;



&lt;p&gt;Now you should understand the context of being specific when using alternative&lt;br&gt;
texts. You might not see the need, you probably would not need it, but a whole&lt;br&gt;
lot of users with disabilities need it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Design your forms for Accessibility&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ensure you add &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; to your form elements though they might not be visible.&lt;br&gt;
You can add labels for screen readers and still hide them from displaying to&lt;br&gt;
other users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"./contact.php"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"fullname"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Full name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fullname"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"fullname"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email address&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Telephone&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"phone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure that your &lt;code&gt;for&lt;/code&gt; attribute matches the &lt;code&gt;id&lt;/code&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Always specify your web app language&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html lang="en-US"&amp;gt; // American english

 &amp;lt;html lang="en-UK"&amp;gt; // British english

 &amp;lt;html lang="fr"&amp;gt; // French
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your app supports multiple languages or translations, ensure to specify that&lt;br&gt;
too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Don’t use tables for anything except tabular data&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t auto-play video, music or other media files&lt;/strong&gt; (Please avoid this)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ensure that links are recognizable. Either underlined or with a different
colour&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Always provide a skip to main content option&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skipping to main content links are useful for users who use keyboard navigation&lt;br&gt;
only&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
...
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Get Started&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
...
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
   Our story is a story which explains another story. Cut the crap this is too long and I don't want to read it.
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
...
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- page specific content --&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt; Here's the main stuff bro &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reduce your divs and make use of semantic elements&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTML5 provides additional elements, such as &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; , &lt;code&gt;section&lt;/code&gt; and &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;,&lt;br&gt;
to better structure your content.&lt;/p&gt;




&lt;p&gt;I’d stop here as we have tons of accessibility guidelines, but don’t worry, I’ve&lt;br&gt;
included links for further reading below :)&lt;/p&gt;

&lt;h3&gt;
  
  
  The A11y project
&lt;/h3&gt;

&lt;p&gt;This is a community-driven effort to make web accessibility easier with tons of&lt;br&gt;
resources, events, patterns, checklists and lots more to help you build more&lt;br&gt;
accessible applications. &lt;a href="https://a11yproject.com/"&gt;https://a11yproject.com/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Accessibility can be a complex and difficult topic. The Accessibility Project&lt;br&gt;
understands this and wants to help make it easier to implement on the web.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Web accessibility tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ally.css&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This CSS file intends to warn developers about possible risks and mistakes that&lt;br&gt;
exist in HTML code. It can also be used to roughly evaluate a site’s quality by&lt;br&gt;
simply including it as an external stylesheet.&lt;/p&gt;

&lt;p&gt;Get the Ally.css built by &lt;a href="https://github.com/ffoodd"&gt;Gaël Poupard&lt;/a&gt;&lt;br&gt;
&lt;a href="https://ffoodd.github.io/a11y.css/"&gt;here&lt;/a&gt; or download the equivalent web&lt;br&gt;
extension (chrome, firefox and opera) Alix built by &lt;a href="https://medium.com/u/f7f8398c3660"&gt;Ire&lt;br&gt;
Aderinokun&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/ireade/alix"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chrome lighthouse&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lighthouse is an &lt;a href="https://github.com/GoogleChrome/lighthouse"&gt;open-source&lt;/a&gt;,&lt;br&gt;
automated tool for improving the quality of web pages. You can run it against&lt;br&gt;
any web page, public or requiring authentication. It has audits for performance,&lt;br&gt;
accessibility, progressive web apps, and more. Read my previous article:&lt;br&gt;
&lt;a href="https://bolajiayodeji.com/introduction-to-chrome-lighthouse/"&gt;Introduction to chrome&lt;br&gt;
lighthouse&lt;/a&gt; to get&lt;br&gt;
started.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Contrast Checker&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check the contrast of your colour design for accessibility based on Web Content&lt;br&gt;
Accessibility Guideline (WCAG). Check it &lt;a href="https://contrastchecker.com/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NoCoffee&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A chrome extension which is helpful for understanding the problems faced by&lt;br&gt;
people with slight to extreme vision problems. Download&lt;br&gt;
&lt;a href="https://chrome.google.com/webstore/detail/nocoffee/jjeeggmbnhckmgdhmgdckeigabjfbddl"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  A full list of web accessibility tools can be found
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/WAI/ER/tools/"&gt;here&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/WCAG20/"&gt;Web Content Accessibility Guidelines (WCAG 2.0)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3docs.com/learn-html/html-language-codes.html"&gt;HTML Language
Codes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.giftegwuenu.com/guide-to-using-alternative-text-on-images"&gt;Guide to using Alternative Texts on
images&lt;/a&gt;
by &lt;a href="https://medium.com/u/46bccfc2f42c"&gt;Egwuenu Gift&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://a11yproject.com/posts/creating-valid-and-accessible-links/"&gt;Creating valid and accessible
links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://a11yproject.com/posts/aria-landmark-roles/"&gt;ARIA Landmark roles and HTML5 implicit
mapping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://a11yproject.com/posts/getting-started-with-nvda/"&gt;Introduction to NDVA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://a11yproject.com/posts/how-to-hide-content/"&gt;How-to hide content but still make it accessible to screen
readers.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://a11yproject.com/posts/using-caption-services-with-html5-video/"&gt;How-to: Using caption services with HTML5
video&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.paciellogroup.com/blog/2015/01/basic-screen-reader-commands-for-accessibility-testing/"&gt;Basic screen reader commands for accessibility
testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  A full list of web accessibility resources can be found
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://a11yproject.com/resources"&gt;here&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Everyone should be able to access and enjoy the web irrespective of their&lt;br&gt;
challenges or limitations. As developers, we’re building solutions for &lt;strong&gt;every&lt;br&gt;
user&lt;/strong&gt; and not just &lt;strong&gt;some users&lt;/strong&gt;. As much as we focus on UI/UX, we should also&lt;br&gt;
put extra focus on accessibility. Thanks for reading!&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OIKe4B7n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2ABQcPB-Ak2H8VA0AT.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OIKe4B7n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/0%2ABQcPB-Ak2H8VA0AT.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Like this article? Kindly follow me on twitter&lt;br&gt;
&lt;a href="https://twitter.com/iambolajiayo"&gt;@iambolajiayo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>web</category>
      <category>a11y</category>
    </item>
    <item>
      <title>Introduction to JavaScript Switch Cases</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Wed, 13 Mar 2019 05:38:46 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/introduction-to-javascript-switch-cases-4mp4</link>
      <guid>https://dev.to/bolajiayodeji/introduction-to-javascript-switch-cases-4mp4</guid>
      <description>&lt;p&gt;In this short article, I will introduce you to JavaScript switch cases and how&lt;br&gt;
to use them with practical examples.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS: This article is not for those without any JavaScript knowledge, it is&lt;br&gt;
expected that you're taking some tutorial or course and you just got to the&lt;br&gt;
switch cases section.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This article will explain better with more practical examples to help you&lt;br&gt;
understand switch cases in depth.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basic JavaScript knowledge&lt;/li&gt;
&lt;li&gt;Code editor&lt;/li&gt;
&lt;li&gt;Web Browser&lt;/li&gt;
&lt;li&gt;Your brain :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;switch&lt;/code&gt; statement can basically replace multiple &lt;code&gt;if&lt;/code&gt; checks in JavaScript.&lt;/p&gt;

&lt;p&gt;It gives a more descriptive way to compare a value with multiple variants.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Switch Syntax&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;switch&lt;/code&gt; has one or more &lt;code&gt;case&lt;/code&gt; blocks and an optional default case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch(x) {
  case 'value1':  // if (x === 'value1')
    //code here
    [break]

  case 'value2':  // if (x === 'value2')
    //code here
    [break]

  default:
    //code here
    [break]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The value of &lt;code&gt;x&lt;/code&gt; is checked for strict equality to the value from the first
&lt;code&gt;case&lt;/code&gt; (that is, &lt;code&gt;value1&lt;/code&gt;) then to the second (&lt;code&gt;value2&lt;/code&gt;) and so on.&lt;/li&gt;
&lt;li&gt;If the equality is found, &lt;code&gt;switch&lt;/code&gt; starts to execute the code starting from the
corresponding &lt;code&gt;case&lt;/code&gt;, until the nearest &lt;code&gt;break&lt;/code&gt;(or until the end of &lt;code&gt;switch&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;If no case is matched then the &lt;code&gt;default&lt;/code&gt; code is executed (if it exists).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Some few real examples&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Simple Play &amp;amp; Pause Switch&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;switch&lt;/code&gt; statement can be used for multiple branches based on a number or&lt;br&gt;
string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (movie) {
  case 'play':
    playMovie();
    break;
  case 'pause':
    pauseMovie();
    break;
  default:
    doNothing();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don’t add a &lt;code&gt;break&lt;/code&gt; statement, the execution will "fall through" to the&lt;br&gt;
next level. It's essential that you deliberately label the fall through with a&lt;br&gt;
comment if you really meant it to aid debugging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (movie) {
  case 'play': // fallthrough
  case 'pause':
    pauseMovie();
    break;
  default:
    doNothing();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default clause is optional. You can have expressions in both the switch part&lt;br&gt;
and the cases if you like; comparisons take place between the two using the&lt;br&gt;
&lt;code&gt;===&lt;/code&gt; operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (3 + 7) {
  case 5 + 5:
    correct();
    break;
  default:
    neverhappens();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple Maths Calc Switch&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let average = 2 + 6;

switch (average) {
  case 4:
    alert( 'Too small' );
    break;
  case 8:
    alert( 'Exactly!' );
    break;
  case 10:
    alert( 'Too large' );
    break;
  default:
    alert( "Incorrect values!" );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;code&gt;switch&lt;/code&gt; starts to compare &lt;code&gt;average&lt;/code&gt;from the first &lt;code&gt;case&lt;/code&gt; variant that&lt;br&gt;
is &lt;code&gt;4&lt;/code&gt;. The match fails.&lt;/p&gt;

&lt;p&gt;Then &lt;code&gt;8&lt;/code&gt;. That’s a match, so the execution starts from &lt;code&gt;case 8&lt;/code&gt;until the nearest&lt;br&gt;
&lt;code&gt;break&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If there is no &lt;strong&gt;&lt;code&gt;break&lt;/code&gt;&lt;/strong&gt; then the execution continues with the next&lt;br&gt;
&lt;strong&gt;&lt;code&gt;case&lt;/code&gt;&lt;/strong&gt; without any checks.&lt;/p&gt;

&lt;p&gt;Here is an example without &lt;code&gt;break&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let average = 2 + 6;

switch (average) {
  case 4:
    alert( 'Too small' );
  case 8:
    alert( 'Exactly!' );
  case 10:
    alert( 'Too big' );
  default:
    alert( "Incorrect values!" );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above we’ll see sequential execution of three &lt;code&gt;alerts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alert( 'Exactly!' );
alert( 'Too big' );
alert( "Incorrect values!" );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;getDay() method switch case&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The getDay() method returns the weekday as a number between 0 and 6.&lt;/p&gt;

&lt;p&gt;(Sunday=0, Monday=1, Tuesday=2 , Wednesday=3, Thursday=4, Friday=5, Saturday=6)&lt;/p&gt;

&lt;p&gt;This example uses the weekday number to calculate the weekday name:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (new Date().getDay()) {
  case 0:
    day = "Sunday";
    break;
  case 1:
    day = "Monday";
    break;
  case 2:
     day = "Tuesday";
    break;
  case 3:
    day = "Wednesday";
    break;
  case 4:
    day = "Thursday";
    break;
  case 5:
    day = "Friday";
    break;
  case 6:
    day = "Saturday";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result of day will be the current weekday in day format&lt;/p&gt;

&lt;p&gt;PS: This would change according to when you’re reading this article&lt;/p&gt;

&lt;p&gt;I wrote this artcle on 01/04/2019 which is a Friday, so the result would be:&lt;/p&gt;

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

&lt;/div&gt;
&lt;h3&gt;
  
  
  The default Keyword
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;default&lt;/strong&gt; keyword specifies the code to run if there is no case match,&lt;br&gt;
more like an else statement:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (new Date().getDay()) {
  case 6:
    text = "Today is Saturday";
    break; 
  case 0:
    text = "Today is Sunday";
    break; 
  default: 
    text = "Its not weekend yet!";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result of text will be:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Its not weekend yet!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;default&lt;/strong&gt; case does not have to be the last case in a switch block:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (new Date().getDay()) {
  default: 
    text = "Its not weekend yet!";
    break;
  case 6:
    text = "Today is Saturday";
    break; 
  case 0:
    text = "Today is Sunday";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If default is not the last case in the switch block, remember to end the&lt;br&gt;
default case with a break.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;There are so many practical examples of switch cases, you can head&lt;br&gt;
&lt;a href="https://javascript.info/switch"&gt;here &lt;/a&gt;to learn more about switch cases.&lt;/p&gt;

&lt;p&gt;If this article helped you, show it by sharing!!&lt;/p&gt;

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

&lt;p&gt;You can follow me on twitter @iambolajiayo&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>developers</category>
    </item>
    <item>
      <title>Manipulating Arrays in JavaScript</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Wed, 13 Mar 2019 05:35:28 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/manipulating-arrays-in-javascript-1lk2</link>
      <guid>https://dev.to/bolajiayodeji/manipulating-arrays-in-javascript-1lk2</guid>
      <description>&lt;p&gt;Arrays have become an important part of any programming language. Most times we&lt;br&gt;
need to do several operations on arrays, hence this article.&lt;/p&gt;

&lt;p&gt;In this article, I would show you various methods of manipulating arrays in&lt;br&gt;
JavaScript [^^]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F880%2F1%2AEK3RyHqvMS-ZIy9UyNMxTA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F880%2F1%2AEK3RyHqvMS-ZIy9UyNMxTA.png"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  What are Arrays in JavaScript?
&lt;/h3&gt;

&lt;p&gt;Before we proceed, you need to understand what arrays really mean.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In JavaScript, an array is a variable that is used to store different data&lt;br&gt;
types. It basically stores different elements in one box and can be later&lt;br&gt;
assesssed with the variable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Declaring an array:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let myBox = [];   // Initial Array declaration in JS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Arrays can contain multiple data types&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let myBox = ['hello', 1, 2, 3, true, 'hi'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Arrays can be manipulated by using several actions known as &lt;strong&gt;methods.&lt;/strong&gt; Some of&lt;br&gt;
these methods allow us to add, remove, modify and do lots more to arrays.&lt;/p&gt;

&lt;p&gt;I would be showing you a few in this article, let’s roll :)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NB: I used &lt;strong&gt;Arrow functions&lt;/strong&gt; in this post, If you don’t know what this means,&lt;br&gt;
you should read&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
Arrow function is an &lt;strong&gt;ES6 feature&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  toString()
&lt;/h3&gt;

&lt;p&gt;The JavaScript method &lt;code&gt;toString()&lt;/code&gt; converts an array to a string separated by a&lt;br&gt;
comma.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let colors = ['green', 'yellow', 'blue'];
colors.toString();

console.log(colors); // "green,yellow,blue"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  join()
&lt;/h3&gt;

&lt;p&gt;The JavaScript &lt;code&gt;join()&lt;/code&gt; method combines all array elements into a string.&lt;/p&gt;

&lt;p&gt;It is similar to &lt;code&gt;toString()&lt;/code&gt; method, but here you can specify the separator&lt;br&gt;
instead of the default comma.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let colors = ['green', 'yellow', 'blue'];
colors.join('-');

console.log(colors); // "green-yellow-blue"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  concat
&lt;/h3&gt;

&lt;p&gt;This method combines two arrays together or add more items to an array and then&lt;br&gt;
return a new array.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let firstNumbers = [1, 2, 3];
let secondNumbers = [4, 5, 6];

let merged = firstNumbers.concat(secondNumbers);

console.log(merged); // [1, 2, 3, 4, 5, 6]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  push()
&lt;/h3&gt;

&lt;p&gt;This method adds items to the end of an array and &lt;strong&gt;changes&lt;/strong&gt; the original&lt;br&gt;
array.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let browsers = ['chrome', 'firefox', 'edge'];
browsers.push('safari', 'opera mini');

console.log(browsers); 
// ["chrome", "firefox", "edge", "safari", "opera mini"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  pop()
&lt;/h3&gt;

&lt;p&gt;This method removes the last item of an array and &lt;strong&gt;returns&lt;/strong&gt; it&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let browsers = ['chrome', 'firefox', 'edge'];
browsers.pop(); // "edge"

console.log(browsers); // ["chrome", "firefox"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  shift()
&lt;/h3&gt;

&lt;p&gt;This method removes the first item of an array and &lt;strong&gt;returns&lt;/strong&gt; it&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let browsers = ['chrome', 'firefox', 'edge'];
browsers.shift(); // "chrome"

console.log(browsers); // ["firefox", "edge"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  unshift()
&lt;/h3&gt;

&lt;p&gt;This method adds an item(s) to the beginning of an array and &lt;strong&gt;changes&lt;/strong&gt; the&lt;br&gt;
original array.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let browsers = ['chrome', 'firefox', 'edge'];
browsers.unshift('safari');

console.log(browsers); //  ["safari", "chrome", "firefox", "edge"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;You can also add multiple items at once&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  splice()
&lt;/h3&gt;

&lt;p&gt;This method &lt;strong&gt;changes&lt;/strong&gt; an array, by adding, removing and inserting&lt;br&gt;
elements.&lt;/p&gt;

&lt;p&gt;The syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;array.splice(index[, deleteCount, element1, ..., elementN])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Index&lt;/code&gt; here is the starting point for removing elements in the array&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;deleteCount&lt;/code&gt; is the number of elements to be deleted from that index&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;element1, …, elementN&lt;/code&gt; is the element(s) to be added&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Removing items&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;after running &lt;strong&gt;splice()&lt;/strong&gt;, it returns the array with the item(s) removed and&lt;br&gt;
removes it from the original array.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let colors = ['green', 'yellow', 'blue', 'purple'];
colors.splice(0, 3);
console.log(colors); // ["purple"]
// deletes ["green", "yellow", "blue"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NB&lt;/strong&gt;: The deleteCount does not include the last index in range.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the second parameter is not declared, every element starting from the given&lt;br&gt;
index will be removed from the array:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let colors = ['green', 'yellow', 'blue', 'purple'];
colors.splice(3);
console.log(colors); // ["green", "yellow", "blue"]
// deletes ['purple']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In the next example we will remove 3 elements from the array and replace them&lt;br&gt;
with more items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let schedule = ['I', 'have', 'a', 'meeting', 'tommorrow'];
// removes 4 first elements and replace them with another
schedule.splice(0, 4, 'we', 'are', 'going', 'to', 'swim');
console.log(schedule); 
// ["we", "are", "going", "to", "swim", "tommorrow"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adding items&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To add items, we need to set the &lt;code&gt;deleteCount&lt;/code&gt; to zero&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let schedule = ['I', 'have', 'a', 'meeting', 'with'];
// adds 3 new elements to the array
schedule.splice(5, 0, 'some', 'clients', 'tommorrow');
console.log(schedule); 
// ["I", "have", "a", "meeting", "with", "some", "clients", "tommorrow"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  slice()
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;This method is similar to &lt;code&gt;splice()&lt;/code&gt; but very different. It returns subarrays&lt;br&gt;
instead of substrings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This method &lt;strong&gt;copies&lt;/strong&gt; a given part of an array and returns that copied part as&lt;br&gt;
a new array. &lt;strong&gt;It does not change the original array.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;array.slice(start, end)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a basic example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let numbers = [1, 2, 3, 4]
numbers.slice(0, 3)
// returns [1, 2, 3]

console.log(numbers) // returns the original array
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The best way to use &lt;code&gt;slice()&lt;/code&gt; is to assign it to a new variable.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let message = 'congratulations'
const abbrv = message.slice(0, 7) + 's!'; 
console.log(abbrv) // returns "congrats!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  split()
&lt;/h3&gt;

&lt;p&gt;This method is used for &lt;strong&gt;strings&lt;/strong&gt;. It divides a string into substrings and&lt;br&gt;
returns them as an array.&lt;/p&gt;

&lt;p&gt;Here’s the syntax:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string.split(separator, limit);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;separator&lt;/code&gt; here defines how to split a string either by a comma.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;limit&lt;/code&gt; determines the number of splits to be carried out
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let firstName = 'Bolaji';
// return the string as an array
firstName.split() // ["Bolaji"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;another example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let firstName = 'hello, my name is bolaji, I am a dev.';
firstName.split(',', 2); // ["hello", " my name is bolaji"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NB:&lt;/strong&gt; If we declare an empty array, like this: &lt;em&gt;&lt;code&gt;firstName.split('');&lt;/code&gt;&lt;/em&gt; then&lt;br&gt;
each item in the string will be divided as substrings:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let firstName = 'Bolaji';
firstName.split('') // ["B", "o", "l", "a", "j", "i"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  indexOf()
&lt;/h3&gt;

&lt;p&gt;This method looks for an item in an array and returns &lt;strong&gt;the index&lt;/strong&gt; where it was&lt;br&gt;
found else it returns &lt;code&gt;-1&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits = ['apple', 'orange', false, 3]
fruits.indexOf('orange'); // returns 1
fruits.indexOf(3); // returns 3
friuts.indexOf(null); // returns -1 (not found)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  lastIndexOf()
&lt;/h3&gt;

&lt;p&gt;This method works the same way &lt;strong&gt;indexOf()&lt;/strong&gt; does except that it works from&lt;br&gt;
right to left. It returns the last index where the item was found&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fruits = ['apple', 'orange', false, 3, 'apple']
fruits.lastIndexOf('apple'); // returns 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  filter()
&lt;/h3&gt;

&lt;p&gt;This method creates a new array if the items of an array pass a certain&lt;br&gt;
condition.&lt;/p&gt;

&lt;p&gt;The syntax is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let results = array.filter(function(item, index, array) {
  // returns true if the item passes the filter
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Checks users from Nigeria&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const countryCode = ['+234', '+144', '+233', '+234'];
const nigerian = countryCode.filter( code =&amp;gt; code === '+234');
console.log(nigerian); // ["+234", "+234"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  map()
&lt;/h3&gt;

&lt;p&gt;This method creates a new array by manipulating the values in an array.&lt;/p&gt;

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

&lt;p&gt;Displays usernames on a page. (Basic friend list display)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userNames = ['tina', 'danny', 'mark', 'bolaji'];
const display = userNames.map(item =&amp;gt; {
 '&amp;lt;li&amp;gt;' + item + '&amp;lt;/li&amp;gt;';
})
const render = '&amp;lt;ul&amp;gt;' + display.join('') + '&amp;lt;/ul&amp;gt;';

document.write(render);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F880%2F1%2AobuBZKFb5vKmUP7D4TX2XA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F880%2F1%2AobuBZKFb5vKmUP7D4TX2XA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// adds dollar sign to numbers
const numbers = [10, 3, 4, 6];
const dollars = numbers.map( number =&amp;gt; '$' + number);
console.log(dollars);
// ['$10', '$3', '$4', '$6'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  reduce()
&lt;/h3&gt;

&lt;p&gt;This method is good for calculating totals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;reduce()&lt;/strong&gt; is used to calculate a single value based on an array.&lt;/p&gt;

&lt;p&gt;The syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let value = array.reduce(function(previousValue, item, index, array) {
  // ...
}, initial);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To loop through an array and sum all numbers in the array up, we can use the for&lt;br&gt;
of loop.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numbers = [100, 300, 500, 70];
let sum = 0;
for (let n of numbers) {
sum += n;
}
console.log(sum);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s how to do same with &lt;code&gt;reduce()&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numbers = [100, 300, 500, 70];
const sum = numbers.reduce((accummulator, value) =&amp;gt;
accummulator + value
, 0);

console.log(sum); // 970
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;If you omit the initial value, the &lt;em&gt;total&lt;/em&gt; will by default start from the first&lt;br&gt;
item in the array.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numbers = [100, 300, 500, 70];
const sum = numbers.reduce((accummulator, value) =&amp;gt; accummulator + value);

console.log(sum); // still returns 970
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The snippet below shows how the &lt;strong&gt;reduce()&lt;/strong&gt; method works with all four&lt;br&gt;
arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;source: MDN Docs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F880%2F1%2ACbd9qR_vy71qZjEQCFpCLQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F880%2F1%2ACbd9qR_vy71qZjEQCFpCLQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More insights into the &lt;strong&gt;reduce()&lt;/strong&gt; method and various ways of using it can be&lt;br&gt;
found &lt;a href="https://medium.freecodecamp.org/reduce-f47a7da511a9" rel="noopener noreferrer"&gt;here&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  forEach()
&lt;/h3&gt;

&lt;p&gt;This method is good for iterating through an array.&lt;/p&gt;

&lt;p&gt;It applies a function on all items in an array&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const colors = ['green', 'yellow', 'blue'];

colors.forEach((item, index) =&amp;gt; console.log(index, item));
// returns the index and the every item in the array
// 0 "green"
// 1 "yellow"
// 2 "blue"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;iteration can be done without passing the index argument&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const colors = ['green', 'yellow', 'blue'];

colors.forEach((item) =&amp;gt; console.log(item));
// returns every item in the array
// "green"
// "yellow"
// "blue"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  every()
&lt;/h3&gt;

&lt;p&gt;This method checks if all items in an array pass the specified condition and&lt;br&gt;
return &lt;code&gt;true&lt;/code&gt; if passed, else &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;check if all numbers are positive&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numbers = [1, -1, 2, 3];
let allPositive = numbers.every((value) =&amp;gt; {
 value &amp;gt;= 0;
})

console.log(allPositive); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  some()
&lt;/h3&gt;

&lt;p&gt;This method checks if an item (one or more) in an array pass the specified&lt;br&gt;
condition and return true if passed, else false.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;c*hecks if at least one number is positive*&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numbers = [1, -1, 2, 3];

let atLeastOnePositive = numbers.some((value) =&amp;gt; {
 value &amp;gt;= 0;
})
console.log(atLeastOnePositive); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  includes()
&lt;/h3&gt;

&lt;p&gt;This method checks if an array contains a certain item. It is similar to&lt;br&gt;
&lt;code&gt;.some()&lt;/code&gt;, but instead of looking for a specific condition to pass, it checks if&lt;br&gt;
the array contains a specific item.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let users = ['paddy', 'zaddy', 'faddy', 'baddy'];
users.includes('baddy'); // returns true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If the item is not found, it returns &lt;code&gt;false&lt;/code&gt;&lt;/p&gt;



&lt;p&gt;There are more array methods, this is just a few of them. Also, there are tons&lt;br&gt;
of other actions that can be performed on arrays, try checking MDN docs&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
for deeper insights.&lt;/p&gt;
&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;toString()&lt;/strong&gt; converts an array to a string separated by a comma.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;join()&lt;/strong&gt; combines all array elements into a string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;concat&lt;/strong&gt; combines two arrays together or add more items to an array and then
return a new array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;push()&lt;/strong&gt; adds item(s) to the end of an array and &lt;strong&gt;changes&lt;/strong&gt; the original
array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pop()&lt;/strong&gt; removes the last item of an array and &lt;strong&gt;returns&lt;/strong&gt; it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;shift()&lt;/strong&gt; removes the first item of an array and &lt;strong&gt;returns&lt;/strong&gt; it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;unshift()&lt;/strong&gt; adds an item(s) to the beginning of an array and &lt;strong&gt;changes&lt;/strong&gt; the
original array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;splice()&lt;/strong&gt; &lt;strong&gt;changes&lt;/strong&gt; an array, by adding, removing and inserting elements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;slice()&lt;/strong&gt; &lt;strong&gt;copies&lt;/strong&gt; a given part of an array and returns that copied part as
a new array. &lt;strong&gt;It does not change the original array.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;split()&lt;/strong&gt; divides a string into substrings and returns them as an array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;indexOf()&lt;/strong&gt; looks for an item in an array and returns &lt;strong&gt;the index&lt;/strong&gt; where it
was found else it returns &lt;code&gt;-1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lastIndexOf()&lt;/strong&gt; looks for an item from right to left and returns the last
index where the item was found.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;filter()&lt;/strong&gt; creates a new array if the items of an array pass a certain
condition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;map()&lt;/strong&gt; creates a new array by manipulating the values in an array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;reduce()&lt;/strong&gt; calculates a single value based on an array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;forEach()&lt;/strong&gt; iterates through an array, it applies a function on all items in
an array&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;every()&lt;/strong&gt; checks if all items in an array pass the specified condition and
return true if passed, else false.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;some()&lt;/strong&gt; checks if an item (one or more) in an array pass the specified
condition and return true if passed, else false.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;includes()&lt;/strong&gt; checks if an array contains a certain item.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Let’s wrap it here; Arrays are powerful and using methods to manipulate them&lt;br&gt;
creates the Algorithms real-world applications use.&lt;/p&gt;

&lt;p&gt;Let's do a create a small function, one that converts a post title into a&lt;br&gt;
urlSlug.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;URL slug&lt;/strong&gt; is the exact address of a specific page or post on your site.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you write an article on &lt;strong&gt;&lt;a href="https://medium.com" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/strong&gt; or any other writing platform, your post&lt;br&gt;
title is automatically converted to a slug with white spaces removed, characters&lt;br&gt;
turned to lowercase and each word in the title separated by a hyphen.&lt;/p&gt;

&lt;p&gt;Here’s a basic function that does that using some of the methods we learnt just&lt;br&gt;
now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const url = 'https://bolajiayodeji.com/'
const urlSlug = (postTitle, category) =&amp;gt; {
let postUrl = postTitle.toLowerCase().split(' ');
let postSlug = `${url}` + category + '/' + postUrl.join('-');
return postSlug;
}
let postTitle = 'Introduction to Chrome Lighthouse'
let category = 'dt'
console.log(urlSlug(postTitle, category));

// https://bolajiayodeji.com/dt/introduction-to-chrome-lighthouse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in &lt;code&gt;postUrl&lt;/code&gt;, we convert the string to lowercase then we use the &lt;strong&gt;split()&lt;/strong&gt;&lt;br&gt;
method to convert the string into substrings and returns it in an array&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;["introduction", "to", "chrome", "lighthouse"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;in &lt;code&gt;post slug&lt;/code&gt; we join the returned array with a hyphen and then concatenate it&lt;br&gt;
to the category string and main &lt;code&gt;url&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let postSlug = `${url}` + category + '/' + postUrl.join('-');
postUrl.join('-') // introduction-to-chrome-lighthouse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That’s it, pretty simple, right? :)&lt;/p&gt;




&lt;p&gt;If you’re just getting started with JavaScript, you should check this repository&lt;br&gt;
&lt;a href="https://github.com/BolajiAyodeji/js-code-snippets" rel="noopener noreferrer"&gt;here&lt;/a&gt;, I’m compiling a list&lt;br&gt;
of basic JavaScript snippets ranging from&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrays&lt;/li&gt;
&lt;li&gt;Control flow&lt;/li&gt;
&lt;li&gt;Dom&lt;/li&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Objects&lt;/li&gt;
&lt;li&gt;Operators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading, got any questions or views? Let's discuss in comments.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>arrays</category>
    </item>
    <item>
      <title>How to test a Pull Request locally before Merging.</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Wed, 13 Mar 2019 05:33:46 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/how-to-test-a-pull-request-locally-before-merging-1h29</link>
      <guid>https://dev.to/bolajiayodeji/how-to-test-a-pull-request-locally-before-merging-1h29</guid>
      <description>&lt;p&gt;In this article, I would show you how to check, test and make changes to a pull request before merging.&lt;/p&gt;

&lt;p&gt;So your repository got a new Pull Request?, You don't want to merge it before testing it out yourself locally on your machine. How do you go about it?&lt;/p&gt;

&lt;p&gt;The pull request is available on this git ref &lt;code&gt;pull/{ID}/head&lt;/code&gt; which you can fetch using this, where ID is the pull &lt;code&gt;request id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REQUIREMENTS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Make sure you have a cloned version of the repository on your machine,&lt;br&gt;
Check &lt;em&gt;&lt;a href="https://help.github.com/articles/cloning-a-repository/"&gt;here&lt;/a&gt;&lt;/em&gt; to learn how to clone repositories from GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have your cloned Repository integrated into your &lt;a href="https://en.wikipedia.org/wiki/Integrated_development_environment"&gt;IDE&lt;/a&gt;&lt;br&gt;
preferably &lt;em&gt;&lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt;&lt;/em&gt; [In this&lt;br&gt;
tutorial, I used VsCode]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be conversant with &lt;em&gt;&lt;a href="https://git-scm.com/"&gt;git&lt;/a&gt;&lt;/em&gt; commands&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to your repository folder&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initialize git (you can do that by right-clicking in the root folder)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure your work tree is clean (you can do that by running &lt;code&gt;git status&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the following commands to FETCH the pull request from GitHub where &lt;strong&gt;ID&lt;/strong&gt; is the pull request's ID&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git fetch origin pull/ID/head &amp;amp;&amp;amp; git checkout FETCH_HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or, if you only want to &lt;a href="https://git-scm.com/docs/git-cherry-pick"&gt;cherry pick&lt;/a&gt; it, instead of checking it out, you can use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git fetch origin pull/ID/head &amp;amp;&amp;amp; git cherry-pick FETCH_HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open your IDE (VsCode) Your folder structure should change now pending on the contents of the PR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you have now is the contents of the pull requests and not your master&lt;br&gt;
branch, run your checks and tests to determine if the pull request is worth merging.&lt;/p&gt;

&lt;p&gt;At this point, you can do anything you want with this branch. You can run some local tests, or merge other branches into it, including &lt;code&gt;master&lt;/code&gt;. Make modifications as you see fit!&lt;/p&gt;

&lt;p&gt;Once satisfied &lt;code&gt;git checkout master&lt;/code&gt; to return to the master branch.&lt;/p&gt;

&lt;p&gt;You can also make changes to the pull request and push back to GitHub as a new commit or pull request.&lt;/p&gt;

&lt;p&gt;After making your changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add --all
git commit -m "Modified PR"
git push origin BRANCHNAME (e.g master or test)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it, you have tested the pull request and made changes!&lt;/p&gt;

&lt;p&gt;If this article helped you, share!!!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>versioncontrol</category>
    </item>
    <item>
      <title>How to convert GitHub Markdown files to a simple website</title>
      <dc:creator>Bolaji Ayodeji</dc:creator>
      <pubDate>Wed, 13 Mar 2019 05:32:16 +0000</pubDate>
      <link>https://dev.to/bolajiayodeji/how-to-convert-github-markdown-files-to-a-simple-website-4e14</link>
      <guid>https://dev.to/bolajiayodeji/how-to-convert-github-markdown-files-to-a-simple-website-4e14</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;This little guide demonstrates how to turn any &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;br&gt;
repository with a bunch of &lt;a href="https://en.wikipedia.org/wiki/Markdown" rel="noopener noreferrer"&gt;Markdown&lt;/a&gt;&lt;br&gt;
files into a simple website using &lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://jekyllrb.com/" rel="noopener noreferrer"&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don't need to use the command line or anything other than your browser.&lt;/li&gt;
&lt;li&gt;It doesn't require any knowledge in Jekyll.&lt;/li&gt;
&lt;li&gt;It's completely compatible with any bunch of markdown files you already have in
any existing repository without any modification to those files. That includes
the basic &lt;code&gt;README.md&lt;/code&gt;almost all repositories contain.&lt;/li&gt;
&lt;li&gt;The markdown files will remain just as readable and usable in Github than in
your website.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step by step instructions
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Determine the repository where you want to activate GitHub Pages
&lt;/h3&gt;

&lt;p&gt;You can of course create a new repository if you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the &lt;code&gt;_.config.yml&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;That file should be created on the root of your repository. Here is some content&lt;br&gt;
to copy-paste in it:&lt;/p&gt;

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

plugins:
  - jekyll-relative-links
relative_links:
  enabled: true
  collections: true
include:
  - CONTRIBUTING.md
  - README.md
  - LICENSE.md
  - COPYING.md
  - CODE_OF_CONDUCT.md
  - CONTRIBUTING.md
  - ISSUE_TEMPLATE.md
  - PULL_REQUEST_TEMPLATE.md


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

&lt;/div&gt;

&lt;p&gt;It's basically just a few tuning of GitHub Pages default configuration to have&lt;br&gt;
a better handling of Markdown files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Activate GitHub Pages in your repository configuration
&lt;/h3&gt;

&lt;p&gt;On the GitHub page of your project go into &lt;code&gt;Settings &amp;gt; Options &amp;gt; Github Pages&lt;/code&gt;:&lt;/p&gt;

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

&lt;p&gt;In the &lt;code&gt;Source&lt;/code&gt; option, select &lt;code&gt;master branch&lt;/code&gt; then &lt;code&gt;Save&lt;/code&gt;:&lt;/p&gt;

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

&lt;p&gt;You must also choose a theme:&lt;/p&gt;

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

&lt;p&gt;That's it! Now you can just use the link provided by GitHub to access you&lt;br&gt;
website:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your site is published at &lt;a href="https://bolajiayodeji.github.io/xxxxxx/" rel="noopener noreferrer"&gt;https://bolajiayodeji.github.io/xxxxxx/&lt;/a&gt;&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Usage guide&lt;br&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Any markdown file in your repository will display in your GitHub Pages website.
You just have to use the same path to access it and replace the &lt;code&gt;.md&lt;/code&gt; extension
by &lt;code&gt;.html&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if you want to display your &lt;code&gt;README.md&lt;/code&gt; file, you have to enter the URL as&lt;br&gt;
&lt;code&gt;README.html&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To make links between your Markdown files just use a relative path to the other
Markdown file. The configuration you copy pasted in your &lt;code&gt;_config.yml&lt;/code&gt; provides
a plugin to convert those URLs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So your Markdown files will have correct links both in GitHub and GitHub Pages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The index page of your website can be a &lt;code&gt;index.md&lt;/code&gt; file or a &lt;code&gt;README.md&lt;/code&gt; file.
If both exists the &lt;code&gt;index.md&lt;/code&gt; file has priority.&lt;/li&gt;
&lt;li&gt;You should be able to use any &lt;a href="https://guides.github.com/features/mastering-markdown/" rel="noopener noreferrer"&gt;GitHub Flavored
Markdown&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Known differences between GitHub and GitHub Pages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No automatic links with GitHub Pages. The GitHub Markdown renderer can
automatically detect a simple copy-pasted link and make it a clickable link.
GitHub Pages doesn't propose a feature to reproduce that behaviour, so you'll
have to braces your links with the &lt;code&gt;[]()&lt;/code&gt;syntax.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>markdown</category>
      <category>github</category>
      <category>website</category>
    </item>
  </channel>
</rss>
