<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ shopify - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ shopify - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 07 May 2026 09:27:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/shopify/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build Your First Shopify App: A Beginner’s Guide ]]>
                </title>
                <description>
                    <![CDATA[ Shopify powers more than a million online stores around the world.  Many store features you see every day, such as discounts, bundles, and order fulfillment are built using apps. These apps are created by developers to extend Shopify and solve real p... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-your-first-shopify-app-a-beginners-guide/</link>
                <guid isPermaLink="false">696023bf8de30d6097e30e99</guid>
                
                    <category>
                        <![CDATA[ shopify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ APIs ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Thu, 08 Jan 2026 21:38:07 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767908229340/434160c9-891e-46d9-82fe-905d1b5ef2cb.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><a target="_blank" href="http://shopify.com/">Shopify</a> powers more than a million online stores around the world. </p>
<p>Many store features you see every day, such as discounts, bundles, and order fulfillment are built using apps. These apps are created by developers to extend Shopify and solve real problems for merchants. </p>
<p>If you know JavaScript and basic web development, you already have enough skills to start building Shopify apps.</p>
<p>In this tutorial, you’ll learn what a Shopify app is, how Shopify apps work, and how to set up your development environment. You’ll also see three real examples of popular Shopify apps and how they are built. </p>
<h2 id="heading-what-well-cover">What We’ll Cover</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-a-shopify-app">What Is a Shopify App?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-shopify-apps-work">How Shopify Apps Work</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-setting-up-your-development-environment">Setting Up Your Development Environment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-shopify-apis">Understanding Shopify APIs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-case-study-one-bundle-and-discount-apps">Case Study One: Bundle and Discount Apps</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-case-study-two-printful-and-order-fulfilment">Case Study Two: Printful and Order Fulfilment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-case-study-three-shiprocket-and-shipping-rates">Case Study Three: Shiprocket and Shipping Rates</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-your-shopify-app">Testing Your Shopify App</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-preparing-for-the-shopify-app-store">Preparing for the Shopify App Store</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<p>To follow this tutorial, you should be comfortable with JavaScript and APIs. Some experience with Node.js and npm will help, but you do not need to be an expert. No prior experience with Shopify is required.</p>
<h2 id="heading-what-is-a-shopify-app">What Is a Shopify App?</h2>
<p>A <a target="_blank" href="https://apps.shopify.com/">Shopify app</a> is a web application that connects to a Shopify store. The app runs on your own server or a serverless platform. </p>
<p>It talks to Shopify using <a target="_blank" href="https://shopify.dev/docs/api">secure APIs</a>. When a merchant installs your app, they allow it to access certain store data. This could include products, orders, or customers, depending on the permissions given.</p>
<p>There are different types of Shopify apps. </p>
<p>Public apps are listed on the Shopify App Store and can be installed by any merchant. These apps must pass a review before approval. </p>
<p>Custom apps are built for a single store, and private apps are used only inside a company. </p>
<p>Most Shopify apps include backend code that calls Shopify APIs, a frontend interface shown inside the Shopify Admin, storefront features that shoppers can see, and webhooks that react to store events.</p>
<h2 id="heading-how-shopify-apps-work">How Shopify Apps Work</h2>
<p>When a merchant installs your app, Shopify starts an <a target="_blank" href="https://auth0.com/intro-to-iam/what-is-oauth-2">OAuth process</a>. This is a secure way to ask the merchant for permission. </p>
<p>Once approved, Shopify sends your app an access token. This token allows your app to make API calls to the store.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767768422978/61189891-7a02-449a-9da7-30c6d1116638.png" alt="Oauth flow" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Shopify apps can add screens inside the admin area using <a target="_blank" href="https://shopify.dev/docs/api/app-bridge">App Bridge</a> and Polaris. These tools make your app feel like part of Shopify. Apps can also add features to the storefront using theme app extensions. </p>
<p>Shopify provides both REST and GraphQL APIs. REST is easy to use, but GraphQL is faster and more efficient. Today, most new apps use GraphQL.</p>
<h2 id="heading-setting-up-your-development-environment">Setting Up Your Development Environment</h2>
<p>Before you start coding, you’ll need a few tools. You’ll need to install Node.js and the <a target="_blank" href="https://shopify.dev/docs/api/shopify-cli">Shopify CLI</a>. You’ll also need a <a target="_blank" href="https://www.shopify.com/in/partners">Shopify Partner account</a>. The Partner account lets you create apps and test them without cost.</p>
<p>The Shopify CLI helps you create a starter app quickly. You can generate a working app by running these commands:</p>
<pre><code class="lang-python">shopify app create node
cd my-shopify-app
npm install
shopify app serve
</code></pre>
<p>This creates an app with login, authentication, and an embedded admin interface. It also sets up a secure tunnel so Shopify can reach your local server while you develop.</p>
<h2 id="heading-understanding-shopify-apis">Understanding Shopify APIs</h2>
<p>Shopify provides APIs for almost every part of a store. This includes products, orders, customers, and shipping. Your app can only access data that the merchant has allowed during installation.</p>
<p>Here’s a simple example of fetching products using the GraphQL Admin API:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> fetch <span class="hljs-keyword">from</span> <span class="hljs-string">"node-fetch"</span>;

<span class="hljs-keyword">async</span> function getProducts(shop, token) {
  const query = `
  {
    products(first: <span class="hljs-number">5</span>) {
      edges {
        node {
          id
          title
        }
      }
    }
  }
  `;
  const response = <span class="hljs-keyword">await</span> fetch(
    `https://${shop}/admin/api/<span class="hljs-number">2025</span><span class="hljs-number">-10</span>/graphql.json`,
    {
      method: <span class="hljs-string">"POST"</span>,
      headers: {
        <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
        <span class="hljs-string">"X-Shopify-Access-Token"</span>: token
      },
      body: JSON.stringify({ query })
    }
  );
  const data = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-keyword">return</span> data.data.products.edges;
}
</code></pre>
<p>This function gets the first five products from a store. The access token comes from the OAuth process during app installation.</p>
<h2 id="heading-case-study-one-bundle-and-discount-apps">Case Study One: Bundle and Discount Apps</h2>
<p>Bundle and discount apps help merchants offer deals like “Buy two, get ten percent off.” These apps must work with Shopify’s pricing rules and checkout system. A popular example is the <a target="_blank" href="https://apps.shopify.com/bundle-deals">Bundle Deals app</a>, which shows offers on product and cart pages.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767768457881/f98bd8fc-7659-4841-9dfe-8adb2aa6f191.png" alt="Bundle deals app" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>These apps usually add small UI elements to the storefront using theme app extensions. They use Shopify’s Discount APIs to apply offers safely. </p>
<p>They don’t change checkout directly. Instead, they enhance the storefront and let Shopify handle the final pricing.</p>
<p>A storefront script might look like this:</p>
<pre><code class="lang-python">fetch(<span class="hljs-string">"/apps/bundle-deals/api/bundles?productId=gid://shopify/Product/123"</span>)
  .then((res) =&gt; res.json())
  .then((bundles) =&gt; {
    displayBundles(bundles);
  });
</code></pre>
<p>This code runs in the store’s frontend. It fetches bundle rules from your app server and shows them to shoppers.</p>
<h2 id="heading-case-study-two-printful-and-order-fulfilment">Case Study Two: Printful and Order Fulfilment</h2>
<p><a target="_blank" href="https://apps.shopify.com/printful">Printful</a> is a popular app that connects Shopify stores with a print-on-demand service (for example, T-shirts, Mugs, and so on). When a customer places an order, Printful receives the order and starts production.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767768478088/0f225294-ce0a-429c-a131-d263db439beb.png" alt="Printful app" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Apps like this need access to orders and reliable event handling. They use webhooks to listen for new orders. When Shopify sends a webhook, the app forwards the data to an external system.</p>
<p>Here is a simple webhook example:</p>
<pre><code class="lang-python">app.post(<span class="hljs-string">"/webhooks/orders/create"</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  const order = req.body;

<span class="hljs-keyword">await</span> printfulClient.createOrder({
    external_id: order.id,
    items: order.line_items.map(item =&gt; ({
      variant_id: item.variant_id,
      quantity: item.quantity
    }))
  });
  res.status(<span class="hljs-number">200</span>).send(<span class="hljs-string">"Order processed"</span>);
});
</code></pre>
<p>This keeps Shopify and Printful in sync. The same pattern is used for shipping tools, accounting software, and CRMs.</p>
<h2 id="heading-case-study-three-shiprocket-and-shipping-rates">Case Study Three: Shiprocket and Shipping Rates</h2>
<p><a target="_blank" href="https://apps.shopify.com/shiprocket">Shiprocket</a> helps merchants manage shipping and delivery. Shipping apps often calculate rates in real time and update order status after shipment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767768510499/2e5351a1-c006-4ac2-b373-47acf63189a3.jpeg" alt="Shiprocket app" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Since Shopify restricts what can run during checkout, shipping apps typically calculate rates before checkout begins or use carrier service APIs. A simple rate endpoint might look like this:</p>
<pre><code class="lang-python">app.post(<span class="hljs-string">"/shipping/rates"</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  const { destination, items } = req.body;
  const rates = <span class="hljs-keyword">await</span> fetchCarrierRates(destination, items);

res.json({
    rates: rates.map(rate =&gt; ({
      service_name: rate.name,
      total_price: rate.price
    }))
  });
});
</code></pre>
<p>This lets merchants show shipping options to customers before they reach checkout.</p>
<h2 id="heading-testing-your-shopify-app">Testing Your Shopify App</h2>
<p>Testing is a critical part of building a reliable Shopify app, especially if you plan to submit it to the App Store. Every feature should be tested thoroughly in a development store before you consider a release. A development store lets you simulate real merchant behavior without affecting live data, which makes it ideal for both manual and automated testing.</p>
<p>In addition to live testing, Shopify allows you to <a target="_blank" href="https://mock.shop/">mock API responses</a> during development. Mocking lets you test your business logic without relying on real API calls or rate limits. This is especially useful when simulating error scenarios or incomplete data, such as missing fields or unexpected values.</p>
<p>By combining real store testing with mocked responses, you can be confident that your app behaves correctly in both normal and failure conditions.</p>
<h2 id="heading-preparing-for-the-shopify-app-store">Preparing for the Shopify App Store</h2>
<p>Preparing for the Shopify App Store is an important step if you want to release a public app that merchants can trust and install with confidence. Shopify has a <a target="_blank" href="https://shopify.dev/docs/apps/launch/app-store-review/review-process">formal review process</a>, and your app must meet both technical and policy requirements before it can be listed.</p>
<p>Your app should request only the API permissions that are absolutely necessary for its core functionality. Asking for extra or unrelated permissions is one of the most common reasons apps get rejected. Shopify expects you to clearly explain why each permission is needed and how the data will be used. This helps merchants feel safe when installing your app.</p>
<p>You must also include basic legal and support information. This includes a clear privacy policy that explains what data you collect and how you handle it, terms of service that define usage rules, and a visible support contact such as an email address or help page.</p>
<p>Finally, Shopify looks closely at app quality. Your app should be stable, handle errors gracefully, and be tested across common store scenarios. Clear messaging, predictable behavior, and transparent data usage go a long way in passing the review process.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Building your first Shopify app takes time, but it’s very achievable. Start with login and API calls. Learn how to embed UI inside Shopify. Study real apps from the Shopify app store. Each one solves a different problem using a different design.</p>
<p>As you practice, the pieces will start to fit together. Keep building, testing, and reading the documentation. Your first Shopify app could be the start of something much bigger.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Shopify Email Automation – How to Automatically Send Emails ]]>
                </title>
                <description>
                    <![CDATA[ Email automation is not something new in the e-commerce space. And it's a pretty simple and straightforward concept. Email automation is all about sending emails to customers based on events that occur on your website, like abandoned cart emails, ord... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/shopify-email-automation/</link>
                <guid isPermaLink="false">66d45e46d14641365a0508b6</guid>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shopify ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Edan Ben-Atar ]]>
                </dc:creator>
                <pubDate>Thu, 31 Mar 2022 17:00:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/Shopify-Email-Automation.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Email automation is not something new in the e-commerce space. And it's a pretty simple and straightforward concept.</p>
<p>Email automation is all about sending emails to customers based on events that occur on your website, like abandoned cart emails, order confirmation emails, shipping confirmation emails, and so on.</p>
<p>The result? You save time by not having to do this work manually.</p>
<h2 id="heading-why-email-automation-is-important">Why Email Automation is Important</h2>
<p>Email is still one of the most effective marketing channels. Email marketing has a higher ROI than any other form of <strong>digital advertising</strong>, and even with all the new tools available to us, it’s still the most cost-effective channel.</p>
<p>Adding automation to your emails can take them even further. Emails are automatically sent based on triggers you set up so that they reach your customers when they’re most likely to convert. Automation also allows you to send messages at scale without any manual work.</p>
<p>Email also provides a direct line of communication with your customers and, if done correctly, can be something people look forward to opening.</p>
<p>It’s a powerful tool, but it’s not just about sending more emails — it’s about sending better ones.</p>
<p><a target="_blank" href="https://www.weblime.com/stories/shopify-automation/">Shopify email automation</a> lets you send personalized emails to each customer as they interact with your business individually and receive follow-up messaging based on their purchase behavior, browsing activity, and even gives them recommendations based on their buying history.</p>
<p>This post will cover different types of email automation, what their purpose is, and how it can benefit the customers and e-commerce stores.</p>
<h2 id="heading-why-is-shopify-email-automation-essential">Why is Shopify email automation essential?</h2>
<p>There are many reasons for implementing email automation on your Shopify store. Here are just a few:</p>
<ul>
<li><p>It saves time.</p>
</li>
<li><p>It increases engagement.</p>
</li>
<li><p>It improves conversion rates.</p>
</li>
<li><p>It enhances the customer experience.</p>
</li>
<li><p>It saves time.</p>
</li>
</ul>
<h3 id="heading-saving-time">Saving time</h3>
<p>Email automation can save you a lot of time by automating tedious, repetitive tasks that would otherwise need to be done manually and individually to each recipient.</p>
<p>This is especially useful when sending a large number of emails in a short amount of time, such as in an event invitation or email marketing campaign.</p>
<h3 id="heading-establishing-trust">Establishing trust</h3>
<p>You can use email automation to establish trust with your customers, which will help increase engagement with your brand and business.</p>
<p>You can also use it to build relationships with your subscribers and increase the likelihood that they'll make a purchase or recommend you to their friends and family.</p>
<h3 id="heading-improving-conversion-rates">Improving conversion rates</h3>
<p>As a business owner, you have to think about how you can improve your conversion rate constantly. This is especially true if you're trying to grow your business.</p>
<p>One of the biggest benefits of using <strong>email marketing automation</strong> software is that it can improve your conversion rate.</p>
<p>When used correctly, email automation can help you reach more people in less time. It can also help you get them interested enough about what you have to offer so that they actually buy from you instead of just browsing around aimlessly on your website.</p>
<h2 id="heading-shopify-email-marketing-automation-software">Shopify email marketing automation software</h2>
<h3 id="heading-klavyio">Klavyio</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-162.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Klavyio is a tool that you can use to set up automated email workflows. It’s a third-party tool (not built by Shopify) that integrates with your store and helps you build stronger relationships with your customers, as well as increase sales.</p>
<p>Using Klavyio, you can create emails that are sent automatically when a customer purchases a product from your store or when they abandon their cart. You can also set up emails to be sent at different points after someone spends time browsing your site, or even if no one has visited for a while.</p>
<p>Not sure how you would use Klavyio in your store? Here are some ideas:</p>
<ul>
<li><p>Send an abandoned cart recovery email after someone leaves items in their cart but doesn't purchase them. You can use the personalization features in Klavyio to show the specific products they left behind, so they're more likely to come back and buy.</p>
</li>
<li><p>Send a newsletter about new products or store promotions to your existing customers. This is a great way to let people know about things happening in your store.</p>
</li>
<li><p>Start building a segment of customers who have purchased from you before. Then send them exclusive offers that aren't available to anyone else.</p>
</li>
</ul>
<p>Here's how it works:</p>
<ul>
<li><p>Klaviyo takes all your customer data and allows you to build experience across email, owned channels and measure the results in revenue.</p>
</li>
<li><p>Klaviyo uses machine learning to analyze and group your customers into segments that are most likely to buy.</p>
</li>
<li><p>Klaviyo automatically creates personalized emails based on what each segment is most interested in.</p>
</li>
</ul>
<p>That way, you know exactly what to send and when to send it.</p>
<p>If a customer adds a product to their cart but doesn’t check out, the abandoned cart email is triggered after some time. This mail includes a list of products that were left behind in the shopping cart. This is when customers return to their carts and complete the transaction in many cases.</p>
<p>Someone who adds a product to their cart is a qualified lead. You can use the abandoned cart email automation process to bring them back with their cart and complete their transaction.</p>
<p>Abandoned carts are triggered after a set period of time, usually between 60 minutes and 24 hours. The product list in the mail reminds them what they were doing and leads them back to the checkout page.</p>
<h3 id="heading-zapier">Zapier</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-161.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Zapier is a web-based service that allows you to connect your favorite web apps and automate workflows—without the headache of learning how to code. It’s a great way to extend the functionality of existing apps.</p>
<p>Zapier uses a trigger-action model. A trigger starts a workflow, and an action ends it.</p>
<p>Zapier moves info between your web apps automatically so that you can focus on your most important work.</p>
<p>To use Zapier, you'll first need to select the app(s) you want to create an automation between. You can either search for your app (Shopify, Gmail, and so on) or scroll through the list of popular apps.</p>
<p>Here’s how Zapier can help you:</p>
<ol>
<li><p>Add new leads to a drip campaign</p>
</li>
<li><p>Trigger follow-up emails after a purchase</p>
</li>
<li><p>Send predefined email responses</p>
</li>
<li><p>Forward contact form submissions to your inbox</p>
</li>
<li><p>Add new contacts to your email list</p>
</li>
</ol>
<p>The best part? You don’t need any technical skills or a big budget. If you can point, click, and type, Zapier can help you automate your email marketing—and more.</p>
<p>For email marketing services, this means Zapier can listen for events and then trigger actions in other apps.</p>
<p>For example, when someone subscribes to your mailing list or when someone purchases something from your Shopify store, Zapier can be instructed to send the user's information to your CRM.</p>
<p>Or, if a new Google Sheets row is created with customer/user data—names, emails, phone numbers—Zapier can add that person as a subscriber to your mailing list automatically.</p>
<h3 id="heading-integromat">Integromat</h3>
<p>Integromat is a powerful workflow automation platform with a focus on scalability, reliability, and flexibility. It enables you to connect Shopify triggers and actions to other apps, web services, or API endpoints.</p>
<p>The platform offers a range of capabilities such as complete control over data flow, API creation, and management tools for developers, as well as scenario builder for non-technical users.</p>
<p>Integromat also allows you to automate complex processes that would otherwise require hiring experienced developers.</p>
<p>Here are some of the things you can do using this integration:</p>
<ul>
<li><p>Send out welcome emails, confirmations, and reviews as soon as your customers sign up to your store or place an order on it</p>
</li>
<li><p>Use different templates based on the product bought by each customer</p>
</li>
<li><p>Segment your subscribers based on their activity, location, and purchase history.</p>
</li>
</ul>
<h2 id="heading-takeaways">Takeaways</h2>
<p>Shopify email automation can be your sales partner if you implement it wisely.</p>
<p>Email automation will probably become your best friend in the long run, especially when it comes to marketing. And if you're having a hard time deciding which strategy to go for, then think of this: email automation is designed to help you improve your sales experience and, ultimately, increase sales.</p>
<p>And it's not just about marketing. Email automation can be used throughout the customer journey to improve their experience as well.</p>
<p>Now that you know more about <strong>Shopify email automation</strong>, there's no reason not to research and learn more about it – because there is definitely a lot for you out there.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Choose a CMS – WordPress vs Ghost vs Shopify ]]>
                </title>
                <description>
                    <![CDATA[ WordPress, Shopify, and Ghost are some of the most powerful and popular CMS platforms out there. And you might wonder why so many people use them. Well, it's because they're easy to use, cost-effective, and highly efficient. With WordPress, Shopify, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chose-a-cms-wordpress-vs-shopify-vs-ghost/</link>
                <guid isPermaLink="false">66d45e3f3a8352b6c5a2aa32</guid>
                
                    <category>
                        <![CDATA[ blog ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ghost ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shopify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WordPress ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Edan Ben-Atar ]]>
                </dc:creator>
                <pubDate>Wed, 02 Feb 2022 17:05:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/WordPress-vs-Ghost-vs-Shopify.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>WordPress, Shopify, and Ghost are some of the most powerful and popular CMS platforms out there.</p>
<p>And you might wonder why so many people use them. Well, it's because they're easy to use, cost-effective, and highly efficient.</p>
<p>With WordPress, Shopify, and Ghost, you can create a website from scratch in a matter of minutes.</p>
<p>Tailored to your needs, these <a target="_blank" href="https://www.weblime.com/stories/top-website-builders">powerful website builders</a> can help you achieve anything from building an e-commerce website to starting your own blog or showcasing your portfolio.</p>
<p>It's no wonder why so many businesses choose these platforms. But which one should you choose?</p>
<p>We can't simply say that one is better than the other, because there's no single solution that will work in every situation.</p>
<p>So in this article, we'll cover the three platforms and look at their strengths and weaknesses so that you can figure out what will work best for your particular situation.</p>
<h2 id="heading-if-you-want-to-build-a-blog-from-scratch-use-ghost">If you Want to Build a Blog From Scratch – Use Ghost</h2>
<p>If you are a blogger who is looking for an open-source platform, <a target="_blank" href="https://ghost.org/">Ghost</a> might be the perfect choice for you.</p>
<p>The fact that it’s open-source enables you to alter the code of the platform, customize it, and make it more suitable to your writing needs.</p>
<p>And even if you’re not a coder, you can get help from other users who are willing to contribute to the community by fixing bugs or adding new features.</p>
<p>Tutorials on how to install Ghost on your own web server are available online. You can also choose to go with a hosted plan, which allows you to use themes created by other users instead of relying on the default theme.</p>
<p>Ghost is a platform that is based on Node.js, and it runs using Node.js servers. It comes with a rich plugin system, allowing you to customize your blog to suit your own needs.</p>
<p>Ghost lets you to use Markdown instead of HTML for writing. This makes it easy for you to write directly in the browser window.</p>
<p>If you don’t know about Markdown, it is a lightweight markup language that allows you to write in rich text but with simpler code, as opposed to HTML.</p>
<p>In fact, one of the benefits of Ghost over other platforms is that your posts are written in Markdown rather than HTML or text files, which results in much cleaner code.</p>
<h3 id="heading-you-can-use-ghost-as-a-headless-cms">You Can Use Ghost as a Headless CMS</h3>
<p>Ghost has a flexible architecture, which means it can be used as a headless CMS. In fact, it's one of the most popular headless content management systems in the JAMStack.</p>
<p>A <a target="_blank" href="https://www.freecodecamp.org/news/what-is-headless-cms-explained/">headless CMS</a> allows you to build a front-end website or application, such as a mobile app, with an API that calls the CMS for its data. You can deploy the API and your website or app to separate servers or environments without having to change anything within your content.</p>
<p>Since the API delivers data from the CMS, you will have full control over that data, including permissions, tags, and categories. If you need to make changes to your content, you will only have to make those changes on one end rather than both.</p>
<p>Headless CMSs are often used for building websites and applications with JavaScript frameworks such as AngularJS and React.js​. However, if you need to render a dynamic site with multiple pages using a single API call, this type of CMS can be beneficial as well.</p>
<p>To use a headless CMS, you will need to learn how it works and how to utilize it through its API. This may require additional development resources, depending on your skill level.</p>
<p>This approach is gaining popularity among startups and agencies who want more control over the display of content while still retaining the ability to make updates through a central interface.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/ghost-screenshot-admin.png" alt="Screenshot of Ghost admin interface" width="600" height="400" loading="lazy"></p>
<h3 id="heading-advantages-of-using-ghost">Advantages of Using Ghost</h3>
<p>Ghost is a free, easy-to-use CMS that doesn’t require any kind of coding skills.</p>
<p>Along with simplicity, Ghost CMS comes with lots of out-of-the-box features which make it really appealing to bloggers and small businesses.</p>
<p>You can add multiple authors, set up collaborative writing, track analytics, create polls, customer support forums, manage templates, and much more using drag and drop features.</p>
<p>Things get interesting as you start using third-party apps on Ghost. There are numerous integrations available for installing apps like Google Analytics and Disqus comments.</p>
<p>Some other pros include:</p>
<ul>
<li><p><strong>It has a clean, minimalistic design</strong>. If you want your blog to be beautiful, then Ghost CMS is great for that.</p>
</li>
<li><p><strong>Complete tools</strong>. You get all the tools that are required in creating a blog, starting from the installation to setting up the theme with the drag and drop features.</p>
</li>
<li><p><strong>Customizable themes</strong>. The themes can be customized using the built-in theme editor that makes it really easy for anyone to modify them as per their needs.</p>
</li>
<li><p><strong>Ghost community</strong>. If you’re stuck, you can find help from other Ghost users by going over their forums and asking questions.</p>
</li>
</ul>
<h2 id="heading-if-you-want-to-take-your-website-to-the-next-level-use-wordpress">If You Want to Take Your Website to the Next Level – Use WordPress</h2>
<p>You can use <a target="_blank" href="https://wordpress.org/">WordPress</a> as a simple blogging platform, but it is also a fully-featured content management system (CMS). It allows you to build custom websites and blogs if you want to take your business to the next level.</p>
<p>Because of its popularity, there is an active support community and lots of free training materials.</p>
<p>Tutorials for the basic functionality and more advanced features are widely available online.</p>
<p>WordPress is free, but if you need help installing it or customizing it for your needs, you can purchase web hosting from a reputable company. Hosting costs vary depending on the type of hosting service you choose.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-get-started-with-wordpress/">You can install WordPress yourself</a> or pay someone to do it for you. The WordPress website provides instructions on how to install the software on different server platforms.</p>
<p>Once installed on your server, WordPress will allow you to create your own blog page. You have complete control over the look and feel of your site through the use of themes, which are pre-built designs for the layout of your pages.</p>
<p>Themes are available for purchase or free download from the WordPress website. You can also <a target="_blank" href="https://www.freecodecamp.org/news/learn-how-to-create-your-own-wordpress-theme-from-scratch/">design your own custom theme</a> if you're up to the challenge.</p>
<p>You might want a more complicated site than what is provided by the basic WordPress installation. In that case, you can hire a designer to build you a customized theme or using an existing theme as a framework and add your own custom features through plugins. Plugins extend the features of themes with special design elements and programming functions.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/WordPress-screen-themes.png" alt="Screenshot of WordPress themes in the admin UI" width="600" height="400" loading="lazy"></p>
<h3 id="heading-advantages-of-using-wordpress">Advantages of using WordPress</h3>
<p>WordPress is by far the most customizable option in this list. It features the most comprehensive library of themes and plugins, allows you to edit the source code quite easily, and even write your own custom functionalities.</p>
<p>You can think of WordPress as the CMS that falls between Ghost and Shopify, as it allows you to run an eCommerce store and a blog at the same time by simply installing a compatible theme.</p>
<p>WordPress lets you take your blog to the next level and scale your eCommerce store as your business grows.</p>
<p>The downside is that sooner or later you will need a developer’s help. This is because the more plugins you install, the slower your website will get, and users hate slow websites (not to mention search engines).</p>
<p>Some other pros include:</p>
<ul>
<li><p><strong>Extremely cheap to get started with</strong>. You can get a WordPress website up and running for free, and basic hosting plans start as low as $18.96 per year.</p>
</li>
<li><p><strong>Ability to assign user roles</strong>. At some point during your business growth cycle, you might need to bring in extra people to help you create, edit and publish content. WordPress comes with built-in user roles which will make your life a whole lot easier.</p>
</li>
<li><p><strong>Best marketing plugins on the market</strong>. You can install one of the many SEO plugins available in the plugin directory. Some examples include Yoast or Rank Math. These plugins help you optimize your content (like articles, pages, and even product pages) and increase your chances of outranking your competitors.</p>
</li>
<li><p><strong>A vast array of integrations</strong>. Chances are you will be using 3rd party SaaS products like Mailchimp or ActiveCampaign. Regardless of the service, you will find it extremely easy to integrate them with your website as almost all have created a WordPress plugin.</p>
</li>
<li><p><strong>The biggest online library of resources</strong>. The WordPress community is by far the largest which makes it easy to find answers to all your questions regarding your installation. There are tens of thousands of websites and forums focused solely on WordPress websites featuring tons of information.</p>
</li>
</ul>
<h2 id="heading-if-you-want-the-fastest-way-to-start-an-ecommerce-business-use-shopify">If You Want the Fastest Way to Start an eCommerce Business – Use Shopify</h2>
<p><a target="_blank" href="https://www.shopify.com/">Shopify</a> started in 2006 as an online store for snowboarding equipment. Back then, the CMS ecosystem was lacking a robust and easy-to-use solution, so the Shopify creators decided to code their own.</p>
<p>Needless to say, this was a hit. In the years that followed more and more stores have started to use the Shopify CMS. As of May 2021, more than 1.7 million businesses from some 175 countries use Shopify to run their businesses.</p>
<p>By far the simplest and fastest way to start an eCommerce business, Shopify is mainly used by nontechnical people that want to bring their brick and mortar stores online. In no more than a few minutes you can have your own website up and running and start accepting online payments.</p>
<p>But Shopify is also used by some of the biggest online stores on the Internet, which makes it a great option if you want to scale your business to the next level, and have the funds to do so.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Shopify-screenshot.png" alt="Screenshot of Shopify UI" width="600" height="400" loading="lazy"></p>
<p>Some of Shopify’s advantages:</p>
<ul>
<li><p><strong>Extremely easy to get started with</strong>. The CMS was built with ease of use in mind. Anyone can get a store up and running in no time. You don’t have to know how to code or even how to connect a domain to your website as Shopify does all that for you.</p>
</li>
<li><p><strong>Compatible with most major third-party services</strong>. Shopify connects out of the box with the biggest third-party services, like Klaviyo for email marketing or Facebook Ads for paid advertising.</p>
</li>
<li><p><strong>Plenty of apps in the app store</strong>. If you feel that your store needs additional functionality, like bundle discounts, for example, you will be happy to hear that there are tons of apps that can help you achieve this. Just be careful and look at their cost as they can go up rather quickly.</p>
</li>
</ul>
<p>Some of Shopify’s disadvantages:</p>
<ul>
<li><p><strong>Can get pretty expensive</strong>. Shopify is extremely easy to start with, but that comes with a cost. The cheapest plan (Basic) starts at $29 per month, while the most expensive one (Advanced) reaches $299 per month. The main difference is the commission applied by Shopify on payments.</p>
</li>
<li><p><strong>High payment fees</strong>. You have to take into account that Shopify charges up to a 2% fee on your transactions (on the Basic plan). This commission decreases with the plan to a minimum of 0.5% (on the Advance plan). In comparison, WooCommerce doesn’t charge you a percentage of your sales.</p>
</li>
<li><p><strong>Shopify developers are expensive</strong>. If you want to customize your store beyond basic functionalities you will need the help of a developer, and they are not cheap. However, there are a multitude of apps available that can help you achieve your goals.</p>
</li>
<li><p><strong>Most Shopify Apps have a monthly cost</strong>. You can find free apps in the app store, but most of them have a monthly cost (compared to a fixed one-time fee charged by the vast majority of WordPress plugins).</p>
</li>
<li><p><strong>The blog functionality isn't great</strong>. Shopify is an eCommerce-centric platform so there’s no wonder that they haven’t spent too much time optimizing their blog functionality. Big stores choose to host their blogs on WordPress while keeping their storefront on Shopify.</p>
</li>
</ul>
<p>In conclusion, you can use Ghost to start your blog almost instantly, or Shopify to configure a fast and secure online store. And, if you want to get the best out of both worlds, you might want to go with WordPress.</p>
<p><a target="_blank" href="https://www.weblime.com/stories/the-ultimate-wordpress-guide">The ultimate WordPress guide</a> is a free resource that will help you understand the basics and help you launch your new website in no time, so be sure to give it a read before you make the big decision of choosing a specific platform.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A detailed tutorial: how to use Shopify’s Storefront API with React and Redux ]]>
                </title>
                <description>
                    <![CDATA[ By Chris Frewin E-commerce for all! (…websites, that is ?) Written by Chris August 2018, updated November, 2018 _Courtesy of Negative Space on [pexels.com](https://www.pexels.com/photo/grayscale-photo-of-computer-laptop-near-white-notebook-and-ceram... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-detailed-tutorial-how-to-use-shopifys-storefront-api-with-react-and-redux-37f95cbab7f/</link>
                <guid isPermaLink="false">66c3426e4f7405e6476b014e</guid>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Redux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shopify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 06 Dec 2018 17:56:22 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*cUOknyEHrQ6wGqynmp__Eg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Chris Frewin</p>
<h4 id="heading-e-commerce-for-all-websites-that-is">E-commerce for all! (…websites, that is ?)</h4>
<p><em>Written by <a target="_blank" href="https://medium.com/@frewin.christopher">Chris</a> August 2018, updated November, 2018</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/QjOaB1iMaaTA4wYVDOKhmtNyjYnzcm-DDxjd" alt="Image" width="600" height="400" loading="lazy">
_Courtesy of Negative Space on [pexels.com](https://www.pexels.com/photo/grayscale-photo-of-computer-laptop-near-white-notebook-and-ceramic-mug-on-table-169573/" rel="noopener" target="<em>blank" title=")</em></p>
<h4 id="heading-background-and-motivation">Background and Motivation</h4>
<p>So the motivation here was pretty simple. I wanted my site visitors to be able to browse, search, and select products directly on my custom domain without having to go to our Shopify site.</p>
<p>The secondary motivation is that I’d much rather have my own codebase for a website than use one of Shopify’s factory templates. No offense Shopify team! The templates are modern and clean, but they are rather basic. I’m sure those templates are heavily customizable, but it’s not a stack I know at the moment.</p>
<p>So this is the best of both worlds — my custom React site (already built and online ?), with the added API and checkout process of Shopify!</p>
<p>By the end of this tutorial, you’ll be able to add your Shopify products on <em>any</em> page of your site. The only part of the shopping process that will occur on Shopify is when the user clicks ‘Checkout’.</p>
<p>I’ve created <a target="_blank" href="https://github.com/frewinchristopher/react-redux-shopify-storefront-api-example">an empty boilerplate repository</a> for this tutorial as well.</p>
<p>The motivation specifically for writing here on Medium was simply that I couldn’t find a tutorial on this process myself — so I decided to make one!</p>
<p>I’ve been a professional developer for 4 years now, and programming for 7. I’ve worked in tech stacks from old-school Fortran and Perl, to React, Javascript, Python, and Node.</p>
<p>Siren Apparel is one of my side project / startup / maker companies that I’ve run for 5 years now, and we’ve donated to 5 different police and fire departments so far!</p>
<p>Let’s finally get started with this tutorial.</p>
<h4 id="heading-shopifys-storefront-api">Shopify’s Storefront API</h4>
<p>The wonderful folks at Shopify have put together the <a target="_blank" href="https://help.shopify.com/en/api/custom-storefronts/storefront-api">Storefront API</a>. With the Storefront API, you can create React components to add product pictures, product variations, product sizes, a cart, and ‘add to cart’ and ‘checkout’ buttons into your own, non-Shopify site.</p>
<p>*Note that this tutorial is NOT about <a target="_blank" href="https://github.com/Shopify/polaris">Shopify Polaris</a>, which is used to create components in React for Shopify store management itself.</p>
<h4 id="heading-getting-started-react-js-buy-repository">Getting Started: <code>react-js-buy</code> Repository</h4>
<p>Take a look at <a target="_blank" href="https://github.com/Shopify/storefront-api-examples/tree/master/react-js-buy">this React example built by the Shopify team</a>. Most of the code in this tutorial comes from that repository.</p>
<p>…Did you take a look? Good! ?</p>
<p>Now we’re going to hop right into code! Head to your React site’s root folder and install the <code>shopify-buy</code> module via the terminal:</p>
<pre><code>cd my-awesome-react-project/npm install --save shopify-buy
</code></pre><p>(or <code>yarn add shopify-buy</code> if you prefer <code>yarn</code>)</p>
<p>Then, in your frontend <code>index.js</code>, (NOT <code>App.js</code>!) you will need to import <code>Client</code> from the JS Buy SDK:</p>
<pre><code><span class="hljs-keyword">import</span> Client <span class="hljs-keyword">from</span> <span class="hljs-string">'shopify-buy'</span>;
</code></pre><p>Then add the following configuration object above the <code>ReactDOM.render()</code>call:</p>
<pre><code><span class="hljs-keyword">const</span> client = Client.buildClient({    <span class="hljs-attr">storefrontAccessToken</span>: <span class="hljs-string">'your-access-token'</span>,    <span class="hljs-attr">domain</span>: <span class="hljs-string">'your-shopify-url.myshopify.com'</span>});
</code></pre><p>That’s it for <code>index.js</code> for now — we’ll come back to it soon.</p>
<p>Now we’re going to add in all the components needed for a smooth shopping and checkout experience. Copy all the components from the <code>react-js-buy</code> repository:</p>
<p><code>Cart.js</code></p>
<p><code>LineItem.js</code></p>
<p><code>Product.js</code></p>
<p><code>Products.js</code></p>
<p><code>VariantSelector.js</code></p>
<p>We will paste these components into a<code>components/shopify/</code> folder in your <code>src/</code> folder. You could put these component files anywhere else in the <code>src/</code> folder, if you wished. The rest of the tutorial assumes you have put them in <code>components/shopify/</code> .</p>
<h4 id="heading-modifying-appjs">Modifying App.js</h4>
<p><code>App.js</code> will need extensive changes. First, import that Cart component you just copied into your own project:</p>
<pre><code><span class="hljs-keyword">import</span> Cart <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/shopify/Cart'</span>;
</code></pre><p>If your <code>App.js</code> component was stateless, like mine, you should be safe copying this entire <code>constructor()</code> function:</p>
<pre><code><span class="hljs-keyword">constructor</span>() {    <span class="hljs-built_in">super</span>();    <span class="hljs-built_in">this</span>.updateQuantityInCart = <span class="hljs-built_in">this</span>.updateQuantityInCart.bind(<span class="hljs-built_in">this</span>);    <span class="hljs-built_in">this</span>.removeLineItemInCart = <span class="hljs-built_in">this</span>.removeLineItemInCart.bind(<span class="hljs-built_in">this</span>);    <span class="hljs-built_in">this</span>.handleCartClose = <span class="hljs-built_in">this</span>.handleCartClose.bind(<span class="hljs-built_in">this</span>);}
</code></pre><p>If you already have state, copy only those <code>bind</code> lines. Those three lines are event handler functions that the Shopify cart needs to function properly.</p>
<blockquote>
<p>“But what about state for the cart!?”</p>
</blockquote>
<p>You may ask; or:</p>
<blockquote>
<p>“What about defining those event handlers for the cart!?”</p>
</blockquote>
<p>Indeed, that’s coming, but not yet! ?</p>
<p>You can then append the <code>&lt;Car</code>t/&gt; component to the bottom of <code>your re</code>nder() function, before the ending div.</p>
<p>In my opinion, the cart should be accessible anywhere in your app. I think it makes sense, then, to put the <code>&lt;Car</code>t/&gt; component in the root component of your app — in other w<code>ords,</code> App.js:</p>
<pre><code><span class="hljs-keyword">return</span> (<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>...<span class="hljs-tag">&lt;<span class="hljs-name">Cart</span>    <span class="hljs-attr">checkout</span>=<span class="hljs-string">{this.state.checkout}</span>    <span class="hljs-attr">isCartOpen</span>=<span class="hljs-string">{this.state.isCartOpen}</span>    <span class="hljs-attr">handleCartClose</span>=<span class="hljs-string">{this.handleCartClose}</span>    <span class="hljs-attr">updateQuantityInCart</span>=<span class="hljs-string">{this.updateQuantityInCart}</span>    <span class="hljs-attr">removeLineItemInCart</span>=<span class="hljs-string">{this.removeLineItemInCart}</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>);
</code></pre><p>Again, I haven’t included any code on the event handlers for the cart yet. Additionally, I didn’t address the lack of state components for the cart in App.js.</p>
<p>There is good reason for this.</p>
<p>About halfway through this project, I realized my products component was of course not in my <code>App.js</code> file.</p>
<p>Instead, it was buried about three children components down.</p>
<p>So instead of passing products three levels down to children, and then function handlers all the way back up…</p>
<p>I decided to use…</p>
<p><strong>? Redux!!! ?</strong></p>
<p><strong>Ugh! I know, I know, Redux, while not being very difficult, is a pain in the %*$! to wire up initially with all the boilerplate required. But, if you are a developer working on an E-commerce store or an E-commerce store owner, think of it this way: Redux will enable you to access the state of the cart from any component or page in our website or webapp.</strong></p>
<p><strong>This ability will be essential as Siren Apparel expands and we develop more products. As we create more products, I’ll make a separate dedicated store page with all products, while leaving just a handful of featured products on the homepage.</strong></p>
<p><strong>The ability to access the cart is essential if a user shops around a bit, reads some stories or info about Siren Apparel, and <em>then</em> decides to checkout. It doesn’t matter how much they navigate around, nothing from their cart will be lost!</strong></p>
<p><strong>So, in short, I decided it’s probably better to implement Redux now while the codebase for <a target="_blank" href="https://sirenapparel.us">our site</a> isn’t too large.</strong></p>
<h4 id="heading-implementing-redux-for-shopify-buy-sdk-with-bare-minimum-boilerplate"><strong>Implementing Redux for Shopify Buy SDK With Bare Minimum Boilerplate</strong></h4>
<p><strong>Install NPM packages <code>redux</code> and <code>react-redux</code>:</strong></p>
<p><strong><code>npm install --save redux react-redux</code></strong></p>
<p><strong>In <code>index.js</code> , import <code>Provider</code> from <code>react-redux</code> and your <code>store</code> from <code>./store</code>:</strong></p>
<p><strong><code>import { Provider } from 'react-redux';</code></strong><br><strong><code>import store from './store';</code></strong></p>
<p><strong>Wrap the <code>&lt;Provid</code>er&gt; component with the p<code>assed</code> store aroun<code>d you</code>r&amp;l<code>t;App&gt;</code>;in index.jsto hook up your App to your Redux store:</strong></p>
<p><strong><code>ReactDOM.render(</code></strong><br><strong><code>&lt;Provider store={store}&gt;</code></strong><br>    <strong><code>&lt;IntlProvider locale={locale} messages={flattenMessages(messages[locale.substring(0, 2)])}&gt;</code></strong><br>      <strong><code>&lt;App locale={locale}/&gt;</code></strong><br>    <strong><code>&lt;/IntlProvider&gt;</code></strong><br> <strong><code>&lt;/Provider&gt;,</code></strong><br><strong><code>document.getElementById('root')</code></strong><br><strong><code>);</code></strong></p>
<p><strong>(Note that I also have a <code>&lt;IntlProvid</code>er&gt;, but that<a target="_blank" href="https://medium.com/@sirenapparel/internationalization-and-localization-of-sirenapparel-eu-sirenapparel-us-and-sirenapparel-asia-ddee266066a2">’s in a different post about how I applied internationalization and localization to dynamically render the content on Siren Apparel’s</a> site. A different story for a different day.)</strong></p>
<p><strong>Now of course we haven’t made a <code>./store.js</code> file yet. Create your store in <code>store.js</code>in the <code>src/</code> root and put this in it:</strong></p>
<p><strong><code>import {createStore} from 'redux';</code></strong><br><strong><code>import reducer from './reducers/cart';export default createStore(reducer);</code></strong></p>
<p><strong>Create your reducers file in <code>src/reducers/cart.js</code> and paste this code:</strong></p>
<p><strong><code>// initial state</code></strong><br><strong><code>const initState = {</code></strong><br>  <strong><code>isCartOpen: false,</code></strong><br>  <strong><code>checkout: { lineItems: [] },</code></strong><br>  <strong><code>products: [],</code></strong><br>  <strong><code>shop: {}</code></strong><br><strong><code>}// actions</code></strong><br><strong><code>const CLIENT_CREATED = 'CLIENT_CREATED'</code></strong><br><strong><code>const PRODUCTS_FOUND = 'PRODUCTS_FOUND'</code></strong><br><strong><code>const CHECKOUT_FOUND = 'CHECKOUT_FOUND'</code></strong><br><strong><code>const SHOP_FOUND = 'SHOP_FOUND'</code></strong><br><strong><code>const ADD_VARIANT_TO_CART = 'ADD_VARIANT_TO_CART'</code></strong><br><strong><code>const UPDATE_QUANTITY_IN_CART = 'UPDATE_QUANTITY_IN_CART'</code></strong><br><strong><code>const REMOVE_LINE_ITEM_IN_CART = 'REMOVE_LINE_ITEM_IN_CART'</code></strong><br><strong><code>const OPEN_CART = 'OPEN_CART'</code></strong><br><strong><code>const CLOSE_CART = 'CLOSE_CART'// reducers</code></strong><br><strong><code>export default (state = initState, action) =&gt; {</code></strong><br>  <strong><code>switch (action.type) {</code></strong><br>    <strong><code>case CLIENT_CREATED:</code></strong><br>      <strong><code>return {...state, client: action.payload}</code></strong><br>    <strong><code>case PRODUCTS_FOUND:</code></strong><br>      <strong><code>return {...state, products: action.payload}</code></strong><br>    <strong><code>case CHECKOUT_FOUND:</code></strong><br>      <strong><code>return {...state, checkout: action.payload}</code></strong><br>    <strong><code>case SHOP_FOUND:</code></strong><br>      <strong><code>return {...state, shop: action.payload}</code></strong><br>    <strong><code>case ADD_VARIANT_TO_CART:</code></strong><br>      <strong><code>return {...state, isCartOpen: action.payload.isCartOpen, checkout: action.payload.checkout}</code></strong><br>    <strong><code>case UPDATE_QUANTITY_IN_CART:</code></strong><br>      <strong><code>return {...state, checkout: action.payload.checkout}</code></strong><br>    <strong><code>case REMOVE_LINE_ITEM_IN_CART:</code></strong><br>      <strong><code>return {...state, checkout: action.payload.checkout}</code></strong><br>    <strong><code>case OPEN_CART:</code></strong><br>      <strong><code>return {...state, isCartOpen: true}</code></strong><br>    <strong><code>case CLOSE_CART:</code></strong><br>      <strong><code>return {...state, isCartOpen: false}</code></strong><br>    <strong><code>default:</code></strong><br>      <strong><code>return state</code></strong><br>  <strong><code>}</code></strong><br><strong><code>}</code></strong></p>
<p><strong>Don’t worry, I’m not going to just post this big reducer and not discuss what is going on; we’ll get to each event! There are a few things to note here.</strong></p>
<p><strong>We take the initial state from what the state is written as in the Shopify GitHub example and put it in our <code>initState</code>, namely the following four parts of state:</strong></p>
<p><strong><code>isCartOpen: false,</code></strong><br><strong><code>checkout: { lineItems: [] },</code></strong><br><strong><code>products: [],</code></strong><br><strong><code>shop: {}</code></strong></p>
<p><strong>However, in my implementation, I also create a <code>client</code> part of the state. I call the <code>createClient()</code> function once and then immediately set it in the Redux state in <code>index.js</code> . So let’s head into <code>index.js</code>:</strong></p>
<h4 id="heading-back-to-indexjs"><strong>Back to index.js</strong></h4>
<p><strong><code>const client = Client.buildClient({</code></strong><br>  <strong><code>storefrontAccessToken: 'your-shopify-token',</code></strong><br>  <strong><code>domain: 'your-shopify-url.myshopify.com'</code></strong><br><strong><code>});</code></strong><br><strong><code>store.dispatch({type: 'CLIENT_CREATED', payload: client});</code></strong></p>
<p><strong>In the Shopify buy SDK example, there are a few async calls to get information about the products and store information in React’s <code>componentWillMount()</code> function. That example code looks like this:</strong></p>
<p><strong><code>componentWillMount() {</code></strong><br>    <strong><code>this.props.client.checkout.create().then((res) =&gt; {</code></strong><br>      <strong><code>this.setState({</code></strong><br>        <strong><code>checkout: res,</code></strong><br>      <strong><code>});</code></strong><br>    <strong><code>});this.props.client.product.fetchAll().then((res) =&gt; {</code></strong><br>      <strong><code>this.setState({</code></strong><br>        <strong><code>products: res,</code></strong><br>      <strong><code>});</code></strong><br>    <strong><code>});this.props.client.shop.fetchInfo().then((res) =&gt; {</code></strong><br>      <strong><code>this.setState({</code></strong><br>        <strong><code>shop: res,</code></strong><br>      <strong><code>});</code></strong><br>    <strong><code>});</code></strong><br>  <strong><code>}</code></strong></p>
<p><strong>I opted to do that instead as far upstream of a site load as possible, directly in <code>index.js</code>. Then, I issued a corresponding event when each part of the response has been received:</strong></p>
<p><strong><code>// buildClient() is synchronous, so we can call all these after!</code></strong><br><strong><code>client.product.fetchAll().then((res) =&gt; {</code></strong><br>  <strong><code>store.dispatch({type: 'PRODUCTS_FOUND', payload: res});</code></strong><br><strong><code>});</code></strong><br><strong><code>client.checkout.create().then((res) =&gt; {</code></strong><br>  <strong><code>store.dispatch({type: 'CHECKOUT_FOUND', payload: res});</code></strong><br><strong><code>});</code></strong><br><strong><code>client.shop.fetchInfo().then((res) =&gt; {</code></strong><br>  <strong><code>store.dispatch({type: 'SHOP_FOUND', payload: res});</code></strong><br><strong><code>});</code></strong></p>
<p><strong>By now the reducer is created, and the initialization of the Shopify API <code>client</code> is complete all for <code>index.js</code>.</strong></p>
<h4 id="heading-back-to-appjs"><strong>Back to <code>App.js</code></strong></h4>
<p><strong>Now in <code>App.js</code>, wire up Redux’s store to the App state:</strong></p>
<p><strong><code>import { connect } from 'react-redux';</code></strong></p>
<p><strong>and don’t forget to import the store as well:</strong></p>
<p><strong><code>import store from './store';</code></strong></p>
<p><strong>At the bottom where <code>export default App</code> should be, modify it to this:</strong></p>
<p><strong><code>export default connect((state) =&gt; state)(App);</code></strong></p>
<p><strong>This connects the Redux state to the <code>App</code> component.</strong></p>
<p><strong>Now in the <code>render()</code> function we are able to access the Redux’s state with Redux’s <code>getState()</code> (as apposed to using vanilla react’s <code>this.state</code>):</strong></p>
<p><strong><code>render() {</code></strong><br>    <strong><code>...</code></strong><br>    <strong><code>const state = store.getState();</code></strong><br><strong><code>}</code></strong></p>
<h4 id="heading-finally-the-event-handlers-were-still-in-appjs"><strong>Finally: the Event Handlers (We’re Still in App.js)</strong></h4>
<p><strong>From above, you know that there are only three event handlers that we need in <code>App.js</code>, because the cart uses only three: <code>updateQuantityInCart</code>, <code>removeLineItemInCart</code>, and <code>handleCartClose</code>. The original cart event handlers from the example GitHub repository, which used local component state looked like this:</strong></p>
<p><strong><code>updateQuantityInCart(lineItemId, quantity) {</code></strong><br>  <strong><code>const checkoutId = this.state.checkout.id</code></strong><br>  <strong><code>const lineItemsToUpdate = [{id: lineItemId, quantity: parseInt(quantity, 10)}]return this.props.client.checkout.updateLineItems(checkoutId, lineItemsToUpdate).then(res =&gt; {</code></strong><br>    <strong><code>this.setState({</code></strong><br>      <strong><code>checkout: res,</code></strong><br>    <strong><code>});</code></strong><br>  <strong><code>});</code></strong><br><strong><code>}removeLineItemInCart(lineItemId) {</code></strong><br>  <strong><code>const checkoutId = this.state.checkout.idreturn this.props.client.checkout.removeLineItems(checkoutId, [lineItemId]).then(res =&gt; {</code></strong><br>    <strong><code>this.setState({</code></strong><br>      <strong><code>checkout: res,</code></strong><br>    <strong><code>});</code></strong><br>  <strong><code>});</code></strong><br><strong><code>}handleCartClose() {</code></strong><br>  <strong><code>this.setState({</code></strong><br>    <strong><code>isCartOpen: false,</code></strong><br>  <strong><code>});</code></strong><br><strong><code>}</code></strong></p>
<p><strong>We can refactor them to dispatch events to the Redux store as follows:</strong></p>
<p><strong><code>updateQuantityInCart(lineItemId, quantity) {</code></strong><br>    <strong><code>const state = store.getState(); // state from redux store</code></strong><br>    <strong><code>const checkoutId = state.checkout.id</code></strong><br>    <strong><code>const lineItemsToUpdate = [{id: lineItemId, quantity: parseInt(quantity, 10)}]</code></strong><br>    <strong><code>state.client.checkout.updateLineItems(checkoutId, lineItemsToUpdate).then(res =&gt; {</code></strong><br>      <strong><code>store.dispatch({type: 'UPDATE_QUANTITY_IN_CART', payload: {checkout: res}});</code></strong><br>    <strong><code>});</code></strong><br><strong><code>}</code></strong><br><strong><code>removeLineItemInCart(lineItemId) {</code></strong><br>    <strong><code>const state = store.getState(); // state from redux store</code></strong><br>    <strong><code>const checkoutId = state.checkout.id</code></strong><br>    <strong><code>state.client.checkout.removeLineItems(checkoutId, [lineItemId]).then(res =&gt; {</code></strong><br>      <strong><code>store.dispatch({type: 'REMOVE_LINE_ITEM_IN_CART', payload: {checkout: res}});</code></strong><br>    <strong><code>});</code></strong><br><strong><code>}</code></strong><br><strong><code>handleCartClose() {</code></strong><br>    <strong><code>store.dispatch({type: 'CLOSE_CART'});</code></strong><br><strong><code>}</code></strong><br><strong><code>handleCartOpen() {</code></strong><br>    <strong><code>store.dispatch({type: 'OPEN_CART'});</code></strong><br><strong><code>}</code></strong></p>
<p><strong>If you were following along, I already mentioned that I added my own <code>handleCartOpen</code> function, because I pass that function down as a prop to my <code>&lt;Na</code>v/&gt; component, so a user is able to open and close the cart from a link in the nav. At a future time, I could move that function to the Nav itself instead of passing it as a prop, since of course the Redux store will also be available there!</strong></p>
<h4 id="heading-finally-add-that-component"><strong>Finally Add that  Component!</strong></h4>
<p><strong>So, you’ve got a basic store maybe with some simple <code>href</code>’s that link to the corresponding product on your Shopify store? Ha! Get rid of those, and replace them with your brand spankin’ new <code>&lt;Product</code>s/&gt; component!</strong></p>
<p><strong>First, import the component into wherever your store markup should be (remember, in my code base I’ve put the shopify example components in a folder called <code>shopify/</code>)</strong></p>
<p><strong>This will be wherever your products currently are. (In <a target="_blank" href="https://github.com/frewinchristopher/react-redux-shopify-storefront-api-example">the boilerplate repository</a> I made, I put this in the <code>GenericProductsPage</code> component, to signal that this code could be applied to any page that has a products section):</strong></p>
<p><strong><code>import Products from './shopify/Products';</code></strong></p>
<p><strong>Now finally, that past 15–20 minutes of redux boilerplate code edits pays off: we can grab the <code>products</code> part of our state — not by way of vanilla React state passed down over and over again through props — but through grabbing by way of Redux state, in a neat one liner <code>const state = store.getState();</code>:</strong></p>
<p><strong><code>render () {</code></strong><br>    <strong><code>const state = store.getState(); // state from redux store</code></strong><br>    <strong><code>let oProducts = &lt;Products</code></strong><br>      <strong><code>products={state.products}</code></strong><br>      <strong><code>client={state.client}</code></strong><br>      <strong><code>addVariantToCart={this.addVariantToCart}</code></strong><br>    <strong><code>/&gt;;</code></strong></p>
<p><strong>Don’t forget to drop the component itself into where it should go in your <code>render()</code> function. For me, that location was buried in Bootstrap style classes and HTML:</strong></p>
<p><strong><code>...</code></strong><br><strong><code>&lt;div className="service-content-one"&gt;</code></strong><br>    <strong><code>&lt;div className="row"&gt;</code></strong><br>        <strong><code>&lt;Products/&gt;</code></strong><br>    <strong><code>&lt;/div&gt;{/*/.row*/}</code></strong><br><strong><code>&lt;/div&gt;{/*/.service-content-one*/}</code></strong><br><strong><code>...</code></strong></p>
<p><strong>Finally, we will need a single event function <code>addVariantToCart</code> for the cart to work with this products component. Again, for reference, here is the original, vanilla React local <code>state</code> version of <code>addVariantToCart</code>(again, from the shopify example repository):</strong></p>
<p><strong><code>addVariantToCart(variantId, quantity){</code></strong><br>  <strong><code>this.setState({</code></strong><br>    <strong><code>isCartOpen: true,</code></strong><br>  <strong><code>});const lineItemsToAdd = [{variantId, quantity: parseInt(quantity, 10)}]</code></strong><br>  <strong><code>const checkoutId = this.state.checkout.idreturn this.props.client.checkout.addLineItems(checkoutId, lineItemsToAdd).then(res =&gt; {</code></strong><br>    <strong><code>this.setState({</code></strong><br>      <strong><code>checkout: res,</code></strong><br>    <strong><code>});</code></strong><br>  <strong><code>});</code></strong><br><strong><code>}</code></strong></p>
<p><strong>and the new, Redux-friendly <code>store.dispatch()</code> version:</strong></p>
<p><strong><code>addVariantToCart(variantId, quantity) {</code></strong><br>    <strong><code>const state = store.getState(); // state from redux store</code></strong><br>    <strong><code>const lineItemsToAdd = [{variantId, quantity: parseInt(quantity, 10)}]</code></strong><br>    <strong><code>const checkoutId = state.checkout.id</code></strong><br>    <strong><code>state.client.checkout.addLineItems(checkoutId, lineItemsToAdd).then(res =&gt; {</code></strong><br>      <strong><code>store.dispatch({type: 'ADD_VARIANT_TO_CART', payload: {isCartOpen: true, checkout: res}});</code></strong><br>    <strong><code>});</code></strong><br><strong><code>}</code></strong></p>
<p><strong>which is of course the one we will use. ?</strong></p>
<p><strong>Don’t forget to bind it in the constructor:</strong></p>
<p><strong><code>this.addVariantToCart = this.addVariantToCart.bind(this);</code></strong></p>
<p><strong>Also, you’ll need to connect this component to the store like you did <code>App.js</code> , and import the store:</strong></p>
<p><strong><code>import { connect } from 'react-redux'</code></strong><br><strong><code>import store from '../store';</code></strong></p>
<p><strong>at the top, and (assuming the component where you put the Shopify <code>Product</code> component name is <code>GenericProductPage</code>:</strong></p>
<p><strong><code>export default connect((state) =&gt; state)(GenericProductsPage);</code></strong></p>
<p><strong>at the bottom.</strong></p>
<p><strong>Great! Now, no matter how deeply buried in components, or wherever your products component is declared, it can communicate with the cart’s state!</strong></p>
<h4 id="heading-final-bonus-example-cart-in-your-header-or-nav"><strong>Final BONUS Example: Cart in Your Header or Nav</strong></h4>
<p><strong>If you want to have a ‘Cart’ button in your header / nav, add this button in your Nav component’s render function (again, an example from my current site, which has Bootstrap styles — a very simple version is in the <a target="_blank" href="https://github.com/frewinchristopher/react-redux-shopify-storefront-api-example">boilerplate example</a>:</strong></p>
<p><strong><code>&lt;div className="App__view-cart-wrapper"&gt;</code></strong><br><strong><code>&lt;button className="App__view-cart" onClick={this.props.handleCartOpen}&gt;</code></strong><br>    <strong><code>Cart</code></strong><br>    <strong><code>&lt;/button&gt;</code></strong><br><strong><code>&lt;/div&gt;</code></strong></p>
<p><strong>where <code>handleCartOpen</code> is a new handler method you’ll have to add to <code>App.js</code>:</strong></p>
<p><strong><code>constructor() {</code></strong><br>  <strong><code>super();</code></strong><br>  <strong><code>...</code></strong><br>  <strong><code>this.handleCartOpen = this.handleCartOpen.bind(this);</code></strong><br>  <strong><code>...</code></strong><br><strong><code>}</code></strong></p>
<p><strong>in the constructor. Then when you are referencing your Nav component in App.js (or wherever you place your Nav) you pass the function handler:</strong></p>
<p><strong><code>&lt;Nav handleCartOpen={this.handleCartOpen}/&gt;</code></strong></p>
<p><strong>This could also be refactored to an event in Redux, but since it was only one child down, I did it the vanilla React way.</strong></p>
<h4 id="heading-styling-components"><strong>Styling Component(s)</strong></h4>
<p><strong>I relied on Shopify’s CSS file, <code>app.css</code>, located in the <code>shared/</code> folder in the <code>storefront-api-example</code> repository (you can’t miss it, it’s the only file in <code>shared/</code> )!</strong></p>
<p><strong>Make sure to copy that into your <code>styles/</code> folder or wherever it needs to be and include it in your <code>index.js</code> file. In my <code>index.js</code> it looks like this:</strong></p>
<p><strong><code>import './styles/shopify.css';</code></strong></p>
<p><strong>Since I renamed the <code>app.css</code> which was in the Shopify example repository to <code>shopify.css</code> , and put it folder <code>styles</code>. This convention is also used in the boilerplate repository code.</strong></p>
<p><strong>From here it’s pretty easy to identify where exactly in <code>shopify.css</code> the default bright blue color for the buttons is defined, and so on. I’m going to save detailed CSS customization for you to handle. ?</strong></p>
<p><strong>But who knows, maybe I’ll post on that eventually — but I find the styles from Shopify pretty good and easy enough to modify.</strong></p>
<h4 id="heading-takeaways"><strong>Takeaways</strong></h4>
<p><strong>In my opinion, this is a perfect (non-todo list ?) use of Redux. Redux cleanly organizes the event functions and state of the Shopify cart and makes it easy to access the cart’s state from any other component. This is much easier to maintain than passing pieces of state to children and using multiple event handlers to pass events back up to parent functions all over a React app.</strong></p>
<p><strong>As shown as an example in the tutorial, the cart’s state is accessed easily in the Nav component and the shop section of the front page. I’ll also be able to easily add it to a sort of ‘featured’ product section as well, once Siren Apparel is ready for that.</strong></p>
<h4 id="heading-find-the-code"><strong>Find the Code</strong></h4>
<p><strong>A boilerplate repository of this implementation <a target="_blank" href="https://github.com/frewinchristopher/react-redux-shopify-storefront-api-example">can be found here</a>. It is a near blank <code>create-react-app</code> app, but with all the changes of this tutorial implemented in <code>index.js</code> and <code>App.js</code> , as well as a super basic <code>GenericStorePage</code> and <code>Nav</code> components.</strong></p>
<p><strong>I built the code on the repo while re-reading and updating my own tutorial here, to make sure this tutorial makes sense!</strong></p>
<p><strong>Because I am crazy ?, Siren Apparel’s website is all open-sourced. So if you want to fool around with my implementation, c<a target="_blank" href="https://github.com/frewinchristopher/sirenapparel.us">heck out the repository!</a></strong></p>
<p><strong>I hope you enjoyed this tutorial! If anything isn’t clear or just plain not working, let me know! I’ll try to assist you!</strong></p>
<p><strong>Thanks to <a target="_blank" href="http://css-snippets.com/author/lisa/">Lisa Catalano</a> at CSS-Snippets for <a target="_blank" href="http://css-snippets.com/simple-horizontal-navigation/#code">the simple Nav example</a> which I used in the boilerplate repository!</strong></p>
<p><strong>Cheers! ?</strong></p>
<p><strong>Chris</strong></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build your first Shopify app ]]>
                </title>
                <description>
                    <![CDATA[ By Igor Petrov Why build a Shopify App? I have always been excited about how the e-commerce market is growing, and have made various attempts to dive into this world. About five years ago, a partner and I built an e-commerce website selling and deliv... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-your-first-shopify-app-bc4edef32974/</link>
                <guid isPermaLink="false">66c3506b465d1b2f886ba422</guid>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ruby on Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shopify ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 01 Aug 2018 19:25:14 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*5rTl2RMivof-SHDDYPsN6A.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Igor Petrov</p>
<h3 id="heading-why-build-a-shopify-app">Why build a Shopify App?</h3>
<p>I have always been excited about how the e-commerce market is growing, and have made various attempts to dive into this world. About five years ago, a partner and I built an e-commerce website selling and delivering flowers, a soft toy, and a greeting card packaged together as a gift. This was an idea validation attempt, and we didn’t take it seriously. So it ended soon.</p>
<p>Later, we tried to sell floor tiles (partnering with a guy who had worked in that area for several years) and it didn’t go well, either. Mostly, the reason was the same: it was a side project for us, and we knew nothing about the floor tile market.</p>
<p>But, during this time, we developed a lot of e-commerce websites for our agency’s clients. Most of these websites were built using <strong>Ruby on Rails</strong> and specifically <strong>Spree</strong>. And this direction was successful — we learned a lot about e-commerce website development and typical development problems (as well as marketing, shipping, and different business problems).</p>
<p>This year I’m working with a new partner who had good experience with the <strong>Shopify</strong> platform. We talked a lot and came up to an idea of developing a <a target="_blank" href="https://apps.shopify.com/influencify"><strong>Shopify</strong> app</a>. This platform is growing fast, and there’s a big demand on the market for extending platform possibilities.</p>
<p>Building a product, rather than doing custom development for someone, was exciting for me, too. So these two things — e-commerce and product development — have naturally combined into the idea of a <a target="_blank" href="https://apps.shopify.com/influencify"><strong>Shopify</strong> app</a>.</p>
<h3 id="heading-understanding-app-building-complexity">Understanding app building complexity</h3>
<p>So you’ve come up with an idea for your application. Now you need to decide if your app will interact with merchants’ storefronts by extending templates or injecting some scripts. Or maybe you need to work with some third-party API and integrate it into your app, or extend a <strong>Shopify</strong> Admin.</p>
<p>Each part can be complex enough. So if you just need to do something with <strong>Shopify</strong> store data and output something in the Admin section, you are dealing with 1 type or 1 point of complexity. If you need to work with external APIs and still have some section in Admin, you have 2 points of complexity. And so on.</p>
<h3 id="heading-start-development-with-a-boilerplate">Start development with a boilerplate</h3>
<p>Well, we can see that our app is quite complex (though for customers it looks like an easy one). Since we agreed on app idea and initial <strong>MVP</strong>, I started to research and found that <strong>Shopify</strong> has a great <code>shopify_app</code> <strong>Ruby</strong> gem.</p>
<p>This is a pretty cool stuff that saves you a lot of time: it generates for you a <strong>Shopify</strong> app framework without the need to setup <strong>OAuth</strong> flow manually. Other things to note:</p>
<ul>
<li>Generated Shop model</li>
<li>Simple Webhooks and ScriptTags registering</li>
<li>Authentication approaches</li>
<li>App Proxy verification (for your storefront customizations)</li>
</ul>
<p>I’ve launched a blank app in minutes, not hours.</p>
<h3 id="heading-use-recommended-tools">Use recommended tools</h3>
<p>Next, I have researched how to approach Admin UI in your app. I found out that <strong>Shopify</strong> simplifies this task for you as well with the power of their design framework <a target="_blank" href="https://polaris.shopify.com/"><strong>Shopify Polaris</strong></a>.</p>
<p><a target="_blank" href="https://polaris.shopify.com/"><strong>Polaris</strong></a> is a <strong>React.js</strong> components library, and this is the recommended way for extending the <strong>Shopify</strong> Admin section. Your app will look like a native <strong>Shopify</strong> app with admin sections like “Products” or “Orders” (<strong>Shopify</strong> uses it too, I guess).</p>
<p>You should use it instead of some custom theme, because it’s well documented, supported, and has guidelines.</p>
<h3 id="heading-extending-shopify-admin">Extending Shopify Admin</h3>
<p>After a successful installation of <strong>Shopify Polaris</strong> into the project with the help of <strong>Webpacker</strong> or <strong>Yarn,</strong> you’ll be able to extend the <strong>Shopify</strong> Admin section.</p>
<p>For the welcome page (one that merchants will see after app installation with no data set up yet), then you’ll do these things:</p>
<ul>
<li>Add a route:</li>
</ul>
<pre><code>get ‘/welcome’ =&gt; ‘home#index’
</code></pre><ul>
<li>Create a <strong>Rails</strong> controller:</li>
</ul>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HomeController</span> &lt; <span class="hljs-title">BaseAuthenticatedController</span> <span class="hljs-title">def</span> <span class="hljs-title">index</span> <span class="hljs-title">endend</span></span>
</code></pre><ul>
<li>Add a view template that just renders <strong>React</strong> component with the help of <code>react-rails</code> gem:</li>
</ul>
<pre><code># home/index.html.erb&lt;%= react_component(<span class="hljs-string">"Welcome"</span>, {  <span class="hljs-attr">apiKey</span>: ShopifyApp.configuration.api_key,  <span class="hljs-attr">shopOrigin</span>: <span class="hljs-string">"https://#{ @shop_session&amp;.url }"</span>,  <span class="hljs-attr">debug</span>: Rails.env.development?,  forceRedirect: !Rails.env.development? &amp;&amp; !Rails.env.test?}) %&gt;
</code></pre><ul>
<li>Create a <strong>React</strong> component that renders some <strong>Shopify Polaris</strong> components (like <code>EmptyState</code>, for example).</li>
</ul>
<p>The first step is quite clear for everyone who’s ever worked with <strong>Ruby on Rails</strong>. The second step should be as well, except the fact that you need to inherit your admin controllers from <code>ShopifyApp::AuthenticatedController</code> so every request will be authorized. I’ve created a subclass of this class for all future admin controller classes.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*2BYWJpAZHNIzSgtICBCQFA.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The third step is about rendering. I’ve installed the <code>react-rails</code> gem which comes with a nifty <code>react_component</code> helper, and I’ve added a rendering of a welcome component passing all necessary properties. For Embedded Apps (those that extend <strong>Shopify</strong> Admin) you should pass at least <code>apiKey</code> and <code>shopOrigin</code> options to utilize <a target="_blank" href="https://polaris.shopify.com/components/get-started#using-embedded-components">embedded components</a> coming with <strong>Shopify Polaris</strong>. These <a target="_blank" href="https://polaris.shopify.com/components/get-started#using-embedded-components">embedded components</a> are just <strong>React</strong> wrappers around the <strong>Shopify</strong> Embedded App SDK.</p>
<p>And finally, I’ve written a <code>Welcome</code> component and placed it into the <code>app/javascript/components</code> folder according to <code>config/webpacker.yml</code>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*HL9JrMwbbqMo_i81DxJmMw.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Note that I’ve extracted some boilerplate, like the definition of <code>shopOrigin</code> and <code>apiKey</code> properties, into the <code>BasePage</code> component which is going to be a parent component for each app page. <code>InfluencifyApp</code> is a component that renders the Polaris <code>AppProvider</code> component, <code>Page</code>, inside it, and any children with <code>{this.props.children}</code> inside the <code>Page</code>.</p>
<p>With this setup, I’ve created other components with <code>InfluencifyApp</code> as a root component for each app page.</p>
<h3 id="heading-storefront-customization">Storefront customization</h3>
<p>There’s a good option in <strong>Shopify</strong> that allows you to customize a merchant’s storefronts: Script Tags. They are JavaScript files that will be injected into the storefront template.</p>
<p>You can register them easily using the <code>shopify_app</code> gem. Here is how I’ve registered a script for <a target="_blank" href="https://apps.shopify.com/influencify">Influencify</a> app (at <code>config/initializers/shopify_app.rb</code>):</p>
<pre><code># to include asset_url helperinclude ActionView::Helpers::AssetUrlHelper...config.scripttags = [    {<span class="hljs-attr">event</span>: <span class="hljs-string">'onload'</span>, <span class="hljs-attr">src</span>: -&gt; (domain) { asset_url(<span class="hljs-string">'influencify.js'</span>, <span class="hljs-attr">host</span>: ENV[<span class="hljs-string">'APP_DOMAIN'</span>]) } }]
</code></pre><p>Note that your scripts should be publicly accessible for all merchants across any of your deployments. I mean in terms of Rails, you shouldn’t have a digest in your script’s filename like <code>influencify-dd432js....js</code> , but instead, put the compiled version into a <code>public</code> folder or upload to CDN.</p>
<p>The second option is that you can have entire pages or parts of pages served by your app. That is, in case you need to display something or fetch some data from your injected script, you can register which URLs for merchants will be served by your app. This feature is known as <a target="_blank" href="https://help.shopify.com/en/api/guides/application-proxies">Application Proxies</a>. Again, to implement this in your app is way easier with the help of the <code>shopify_app</code> gem — just follow their <a target="_blank" href="https://github.com/Shopify/shopify_app#app-proxy-controller-generator">guides</a>.</p>
<h3 id="heading-testing">Testing</h3>
<p>Testing a <strong>Shopify</strong> app may be a little tricky, but it’s familiar for anyone who’s ever worked with third-party APIs and tested via tools like <code>localtunnel</code> or <code>ngrok</code>. So each time you’re going to test your app, just launch your favorite tunneling tool and update the “Whitelisted redirection URL(s)” field on your app settings page with a URL to your authentication callback that looks like this: <code>[https://myapp.localtunnel.me/auth/shopify/callback](https://myapp.localtunnel.me/auth/shopify/callback)</code>.</p>
<p>To test your App Proxies endpoints for storefront customizations, you need to update this URL setting as well under the “Extensions” section.</p>
<p>Of course, to test an app you also need a test development store.</p>
<h3 id="heading-deployment">Deployment</h3>
<p>There’s nothing special about deployment, since this is just a regular <strong>Ruby on Rails</strong> application. I’ve deployed my app to the <strong>Heroku</strong> platform with the <strong>Puma</strong> and <strong>Sidekiq</strong> processes specified via the Procfile.</p>
<p>Also, you need to set the environment variables that you are going to use in your app via <code>ENV['SOMETHING']</code>.</p>
<p>One more thing to notice is I’ve added a <strong>Node.js</strong> buildpack, because had issues with building via <strong>Webpack</strong>:</p>
<pre><code>git:(master) heroku buildpacks     === influencify Buildpack URLs1. https:<span class="hljs-comment">//github.com/heroku/heroku-buildpack-ruby2. https://github.com/heroku/heroku-buildpack-nodejs</span>
</code></pre><h3 id="heading-going-further">Going further</h3>
<p>Well, as you can see, building an app the way it’s recommended by <strong>Shopify</strong> includes many different steps, and it may turn out to be a complex task for a non-experienced developer.</p>
<p>Of course, building an app is only the tip of the iceberg. The next steps in a <strong>Shopify</strong> app building venture are making good promo materials, submitting it to the App Store, marketing, and customer support/development after it has been approved.</p>
<p><em>If you liked this post, please click on</em> ✋ <em>to spread the word.</em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
