10 Things we Learned Building Our First Shopify App

building shopify app

When we first started building our Shopify App, we knew there was lots of opportunity—Shopify has a well documented platform with a comprehensive API, and an ecosystem of over 2,000 apps to choose from. Our goal was to build an app that would allow store owners to leverage Facebook Messenger as a powerful abandoned cart recovery tool. 

When we started working on our app, it wasn’t always obvious which API was best suited for the task at hand. We learned a lot from the experience. And since we know there are likely other developers who might be exploring Shopify as a platform to develop on who are also confused where to start, we’ve put together a list of things to keep in mind. Using our Shopify App as an example, I’ll walk through how we built our components and integrated them with Shopify.

Interested in getting started with Shopify app development? Learn more about how to build a Shopify app. Or, for more tools, check out our list of favorite Sublime text plugins.

Build apps for Shopify merchants

Whether you want to build apps for the Shopify App Store, offer private app development services, or are looking for ways to grow your user base, the Shopify Partner Program will set you up for success. Join for free and access educational resources, developer preview environments, and recurring revenue share opportunities.

Sign up

Our Shopify app

Our app has three user-facing components:

Below, we look at each of these components and the lessons learned for each.

Merchant’s app admin

building shopify app: polaris

The user interface of our app is built with Shopify Polaris. Polaris components share the same design language as the rest of the Shopify Admin, resulting in a well thought out and consistent experience across Shopify.

With Polaris in mind, here is what we learned about building our app’s admin.

1. Shopify Polaris

Polaris supports Typescript, a big plus for us. Our front end developers loved the extensive library of components available. The Polaris library includes every general and some not so common components for building an app. In particular, we found the resource list component very useful. It’s a tabular display oriented towards displaying a collection of similar objects, like customers or products.

As a team of developers for whom English is not their first language, the best practices and do’s and don'ts accompanying each component were a big advantage, and helped us understand the right kind of language and text to use.

2. Styling components

Polaris components also come with an extensive prop list for styling components. However, we found that sometimes it wasn’t enough, and wanted more control using CSS. Unfortunately, Polaris does not support styled components, which means we ended up with a bunch of wrapper components to achieve custom styling.

Our advice to developers starting with a similar project: use Polaris as the building blocks for your app. Not only did it save us a lot of time not having to write basic components, but our app also integrates right into the Shopify design.

"Our advice to developers starting with a similar project: use Polaris as the building blocks for your app."

Backend API

For the backend, we started with Shopify’s guide for building an app with Node and React. Using Heroku, we had an app with Shopify authentication running in less than half an hour. When an app is installed, it asks for access to the API scopes you need, depending on the kind of app you are developing. When choosing which scopes to access, keep in mind possible future use cases as well.

You might also like: 10 Ways to Establish Trust on Ecommerce Sites and Apps.

3. Shop identifier

Shopify does not use numerical IDs as unique shop identifiers. Instead, every shop has a subdomain on the myshopify.com domain name. This subdomain is set once the store is created and cannot be changed. We use it as the unique identifier in our database. 

4. Webhooks

Webhooks provide a powerful way to plug into events happening in the Shopify store. There are two store webhooks that in our opinion an app should always subscribe to: app/uninstalled and shop/update.

The uninstall webhook lets us know when a shop uninstalled our app so we can invalidate the entry in our database. A store owner can reinstall an app, which means the onboarding steps need to be triggered again.

The shop update webhook sends us the updated shop information, which has the email address we use to keep in touch with the store owner.

5. API access scopes

One thing that was confusing when starting off was that Shopify only allows one app URL, which could either be a new install for the app, or an existing customer. This distinction needs to be made at our own end with a database query. This limitation is a result of Oauth, which Shopify uses for authentication.

6. Cart permalinks

As one step of our abandoned cart recovery process, we redirect customers to a checkout page with the same cart contents they had previously. It is possible to create cart permalinks, but it’s buried on an unrelated page in the Shopify documentation about theming.

7. Onboarding steps

The app onboarding kicks off the first time a user logs into the app. During this step, we exchange the temporary Shopify access token for a permanent one, create webhooks, and add script tags on Shopify. We store the token and IDs in our database to ensure this step happens only once.

8. Recurring charge updates

We ran into another issue when we added recurring billing to our app. Shopify doesn’t have webhooks for payment status updates. Polling the Billing API to get the status of an active recurring charge for each shop at regular intervals is the only way to validate the charge.

You might also like: User Testing Your Shopify App: Public App Use Cases You Should Test.

Injected script

Shopify provides ways to integrate with the storefront section by directly injecting a script tag into the store. This provides no-holds-barred access to change the experience for the shopper. For security reasons, the script tag does not trigger on the checkout pages.

The script tag(s) are associated with each store, so the URL can be tweaked specifically for every store. However, we opted to go for a single static script tag URL. With this approach, we do not have to dynamically create a script for every request, and our requests are cached across multiple Shopify stores.

When the injected script loads, a window.Shopify object with some basic info about the shop—including the myshopify domain—opens. We use this to get the configuration from the API and initialize our static script.

9. Keeping track of carts

Abandoned cart recovery is the core of our product, and to do this effectively we have to track the cart status as the customer navigates through the store. Every customer who lands on the store gets a 32-digit unique hexadecimal cart ID. We use this cart ID to keep track of customers on Shopify stores. One limitation we ran into is that the cart ID is not constant across page visits until there’s an item added in the cart.

10. Applying discounts automatically

Shopify separates the concepts of a cart and a checkout. A discount code can only be applied to a checkout. Because a script tag does not trigger on the checkout page, it is not possible to use the script tag to add a discount code. It’s possible, however, to “create” shareable links to discount codes, and then redirect the shopper to the link right away. During the checkout, the code will be applied automatically.

Summarizing what we learned

In a nutshell, here are the main lessons we learned:

For everyone:

  • Use Polaris for the front end.
  • Follow best practices when using Polaris components.
  • Create wrapper components to work with styled components.
  • Use shop domain as the unique identifier.
  • Always subscribe to the app/uninstalled and shop/update webhooks.
  • Request access to API scopes considering future use cases.
  • Recurring charges have no webhooks; you will need to poll to get billing updates.
  • Script tags provide a powerful method to alter the customer experience for a store.

When working with carts:

  • Cart ID is only constant after an item is added to cart.
  • At the time, discounts could not be applied to carts, only to checkouts. With the release of the Discounts API, they can now be applied to both.
  • Cart permalinks can be created to directly link to a checkout

Build apps for Shopify merchants

Whether you want to build apps for the Shopify App Store, offer private app development services, or are looking for ways to grow your user base, the Shopify Partner Program will set you up for success. Join for free and access educational resources, developer preview environments, and recurring revenue share opportunities.

Sign up

Final thoughts

There were a few aspects where we found the platform lacking, however nothing that was more than a small obstacle. Shopify’s platform allowed us to quickly provide value to merchants and shoppers alike.

As someone who has worked on custom billing and authentication implementations in the past, achieving the same results on Shopify’s hosted platform was a breeze. Webhooks let us plug into the event stream of the store, and the Polaris library provided us a solid collection of components and script tags that hook into the storefront—in retrospect, the popup and abandoned cart messages are simple components compared to what is actually possible.

What were the biggest lessons you learned building your first Shopify App? Share your experience in the comments below!

Grow your business with the Shopify Partner Program

Learn more