Mar 18, 2024
How to create a Team Environment for Shopify App Dev
Our engineering team shares insights on collaborative Shopify App development, emphasizing the use of Git for version control and Ngrok for secure tunneling, to ensure smooth teamwork and efficient workflow.
Let's say you've just come up with a cool idea for a Shopify App with a friend. You've done some planning, have an idea of how you want to implement your app, and then the moment you create your repository you bump into one of a few issues that means you can't work on it together. Your app is a huge project, you don't want to have to work on it by yourself.
You do some research and you see some people talk about Git and version control online but you can't actually test your code simultaneously. It's a tricky situation but have no fear. At Flare, we’ve been building a Shopify app and after a bit of trial and error, we've managed to come up with a few workarounds to some common issues you might face when attempting to set up a team development environment for a new Shopify App.
It's important to clarify that we are assuming you are using the Node JS starter for your app, however most of these tricks will work in Remix as well, we will try to flag through the article where things will and won't work on other frameworks.
Tunnels (CloudFlare vs. Ngrok)
The big one... Shopify provide a tunnelling service to expose your app to the internet. This is because when you open your app, it's visible as an iFrame inside of Shopify's app pages. The iFrame then renders whatever is in your App Bridge directory, i.e your frontend React (or whatever other) interface you use. The Shopify app page needs to be able to see your code in your local codebase, and as such Shopify use a default tunnel generated in CloudFlare. This is a recent switch as they used to use Ngrok, however CloudFlare tunnels are dynamically allocatable and there's no hassle in the form of setting up an account or creating domains like there is in Ngrok.
That being said, Ngrok has a few things going for it that made it our choice to use as a tunnel provider, these include:
Live traffic monitoring either in your terminal / console, or on their web dashboard
Simulating and repeating network requests through the tunnel
Visibility into live tunnels running and the ability to remotely shut them down from the admin page
TLS/SSL certificates on those tunnel domains
and a few more, but I'll spare you the details. What I won't spare you is a few tips and tricks to get going with Ngrok instead of Shopify's default CloudFlare.
First and foremost, go to Ngrok's website and sign up for an account. Then follow the installation instructions to set up Ngrok in your terminal. Ensure that you and your teammate set up different accounts and different tunnels. You will each want to go to the 'Domains' tab in the left hand panel and create a domain. You get one free static domain per user account without upgrading, this should be free.
Once created, click on the small terminal icon to the right of your Ngrok domain and copy the command to start your tunnel on your local machine. Make sure you're passing the port of your Shopify App server through there as well, it should look something like ngrok http --domain=YOURNGROKDOMAINHERE 4000
in the case that your app port is 4000. Run this in a terminal and you should see a nice Ngrok window appear. Leave this running the background and open a new window and navigate into the root of your Shopify app project.
You can pass your own flags to the npm run dev
command by adding an extra --
before you add your flags, in this case we want to add the --tunnel-url=
flag to our command to specify the domain of our Ngrok tunnel, in which case we use npm run dev -- --tunnel-url=YOURNGROKDOMAINHERE
to force our dev server to run on the tunnel domain that we specify and not generate a random CloudFlare tunnel.
Once we're running both of those commands together, we should be able to access our app on our Ngrok domain.
You might be saying "well now I can connect to my app but my teammate can't run his code at the same time, this didn't help at all..." hold your horses! We've got an app service running but the most important part is where you point it. Read to learn about Git and most importantly, development stores!
Git and Version Control
Now you may have heard of Git and Version Control as one of the key tools in a programmers' tool belt, well those people are wrong... this is the tool belt. A programmer that doesn't use Git is a programmer ready and willing to lose everything to an accidental misclick, a corrupted disk or a cat falling asleep on the backspace key.
Version Control is pretty self explanatory, it is essentially a periodic save of whatever changes you've made to your code. A Git user can regularly make commits to a repository in order to save their code changes. If they should change something that breaks the code, rather than trying to make it work or changing things to try and get it back the way it was, the programmer can just revert back to the previous commit. Think of it as a backup of your code, a time machine.
So let's talk about branches. This is the bit we really want to focus on today. Branches allow us to create separate sets of changes from our code that branch off into different versions. In this case, we are going to cleverly create a development
branch and a main
branch to act as our development and production environments respectively.
We do this simply by running git checkout -b development
in the root folder of our Shopify App. This will switch us to a development
branch. We can make changes in here and when we are happy to move them into main
we can create what is called a pull request to merge the changes in development
into main
. This can be done easily in a remote Git Repository hosted on a platform like GitHub or BitBucket. Creation of Pull Requests (here on referred to as PRs) differs between each of these platforms in the interface, but the concept is still the same, make sure to look up creating a PR in your specific remote repository provider and ensure you are merging development
into main
and not vice versa.
An optional extra that is common amongst large scale companies is to create feature branches which is just a fancy way of saying anytime you want to fix a bug, add a new feature or make any goal based changes, you create a new branch in your repository. In this case, development
would be our base branch so we would create a new branch from development
named after your feature (i.e. added-styling-to-div
) that you would then merge into development
and then eventually into main
to deploy it to your end user. Think of the development
branch as the place that holds all of your upcoming features while you test them and make sure they work, and then main
as the version of your app that your user sees.
In a later article, we will go over how we automatically deploy our app from the main
branch using GitHub Actions.
Development Stores
The crucial finale of this article is how we use development stores. This is where it gets a little tricky, but make sure to stay with us.
Development stores are a way that Shopify allows its app creators to test their apps on a storefront. It is a barebones store that you will have created if you ran that npm run dev
command we discussed in the first part of the article, or you can choose to develop your app on your own store should you configure your app to do so (this won't be covered in this article).
So you and your friend want to develop your app but you can't connect to the same store? Well that's easy... make two more stores. I know this may seem like a cop out, but trust us, we tried a ton of different ways and this is the best way to go about it.
Remember those branches we created earlier in Git? Well here's how this goes down. We want to create a development store for you and your teammate (2 so far), then we want to create a development store for your development
branch in your remote repository (3 in total). Then we're going to create 2 more apps in the Shopify dashboard, one for you and one for your teammate. In our case we have APP NAME - USER FIRST NAME
as our naming format to ensure we won't end up with duplicate development stores.
Anytime you run your code locally, we want to run it off of your Ngrok domain pointing to your personal app. The same goes for your teammate. You make your changes but you don't track your shopify.app.toml
file, then your changes get merged into the dev branch which is running on its own APP NAME - STAGING
app installed on its own development store. Then finally merged into the main
branch that points to your main app and is exposed to all of your users. With this method, you can test changes on your own development stores and merge and conditionally approve change requests before they go out to your users without having to revert changes as often, as well as maintaining your own workspace and not interfering with one another.
Quick Tip - Make sure you have a separate TOML file for both your development environment and your production environment. Personally, I always get confused and irritated having to run the command to change TOML files or check which TOML file I'm using, so I just have two separate directories for my production and development environments with a TOML file in each one respectively. However, you can just be more diligent than myself and use the npm run shopify app config use <CONFIG>
to specify a different configuration TOML file to point to either your personal Ngrok domain or your production app
Conclusion
By now you should have a Git repository in your app with a few branches created, a Ngrok domain acting as a tunnel for your application and a few development stores connected to different versions of your app. That's great! You and your teammate can now make separate commits (after having locally tested code on your own development stores) that can be periodically approved and merged up into main where everyone can see your new feature releases. A few final notes and words of wisdom:
If you choose to add a Theme App Extension UI (start playing with app blocks) you will need to have a local version of your code that is specifically acting as a local copy of the
main
branch. If you try to runnpm run deploy
in your development branch, it will only deploy to your development app and not your users. Read the 'Quick Tip' at the end of the last section of the article for a quick insight into usingnpm run shopify app config use
to address this in one folder.Do not commit your TOML files except for an initial commit to add your production TOML file to the repository. You don't want to overwrite your production TOML file with your local development one, or all of your app users will be routed to your laptop's development server.
With Ngrok's free plan, you have a limit of 1GB of bandwidth, so try not to leave your local server running with Ngrok for too long or you may use up all of your bandwidth very quickly and be forced to stop testing features until the rolling month contract rolls over to the next month.
If you haven't by now, please go and take a look at some of the work we're doing at Flare to try and make e-commerce more sustainable.
Happy coding!