Create your own subscription blog with Shopify


In this article, I’ll show how to start a paid blog with Shopify using HTML, CSS, and Liquid (Shopify’s template language). Even though Shopify’s blogging features are somewhat basic, and there are other online services that specifically help bloggers create blogs that readers can subscribe to for a fee (like Ghost), I’ll explain. why you prefer to use Shopify.

Eh? Shopify for content? Why?

Shopify is arguably the leader in the ecommerce space. It has the most clients and the most ready-made (well executed) features compared to its competitors.

Shopify can make it easy to sell just about anything including subscription services, digital downloads, free swag, and even in-store items through its point of sale system.

I would say most think Shopify is number one in ecommerce, and while there are specialist services out there for selling access to content, I still think Shopify is the better option.

Let’s compare Shopify with Phantom, for example, since Ghost is the fastest growing blogging CMS today.

Shopify Basic and Ghost Pro Basic both cost $ 29 / month. However, Shopify can sell anything, while Ghost can only sell access to subscription– content based. Ghost can’t sell access to content for a one-time fee, or anything else. Shopify wins hands down when it comes to business model flexibility.

Honestly, the only downside is that blogging features are considered the weakest link in Shopify, but if you like to build themes from scratch (which frankly comes with many advantages), then you would be surprised at how powerful and flexible Shopify’s Liquid template language is. I wouldn’t consider Shopify to be an e-commerce Platform, but rather a CMS with roots in e-commerce.

So if you want to leave a new business open to additional / alternative business models, or if you already have a Shopify store with a blog that you want to monetize, let’s get started.


You should be reasonably skilled in web development, understanding at least HTML and CSS. Some knowledge of the Liquid template language that Shopify uses would definitely be beneficial, but not required, as Liquid is fairly easy to learn along the way. (I would recommend checking the Liquid documentation independently.)

You will also need create a Shopify account, which is free for 14 days (no card required). Please note, however, that unless you choose a payment plan, you will not be able to remove password protection on your store.

Step 1: Define the structure of the theme

First, let’s define the theme’s file structure using a mix of required and common files. We won’t use them all in this tutorial, but you can use this structure to launch any barebones Shopify store in the future. The files may be empty at the moment:

├── assets
├── config
│   ├── settings_data.json
│   └── settings_schema.json
├── layout
│   └── theme.liquid
├── sections
├── snippets
└── templates
    ├── 404.liquid
    ├── article.liquid
    ├── blog.liquid
    ├── cart.liquid
    ├── collection.liquid
    ├── customers
    │   ├── account.liquid
    │   ├── activate_account.liquid
    │   ├── addresses.liquid
    │   ├── login.liquid
    │   ├── order.liquid
    │   ├── register.liquid
    │   └── reset_password.liquid
    ├── gift_card.liquid
    ├── index.liquid
    ├── list-collections.liquid
    ├── page.liquid
    ├── password.liquid
    ├── product.liquid
    └── search.liquid

If you are tracking on macOS or Linux, you can use the following commands to generate the structure:

mkdir -p assets snippets sections config layout templates/customers
touch config/settings_data.json config/settings_schema.json
touch layout/theme.liquid
cd templates/customers
touch account.liquid activate_account.liquid addresses.liquid login.liquid order.liquid register.liquid reset_password.liquid
cd ..
touch 404.liquid article.liquid blog.liquid cart.liquid collection.liquid gift_card.liquid index.liquid list-collections.liquid page.liquid password.liquid product.liquid  search.liquid

cd ..

Further reading:

Step 2: Get the theme id

Next, we’ll need to get the theme ID of the default theme (“Debut”) which should already be installed. In the Shopify admin, go to Online Store > Themes > Actions > Modify the code then note the numeric theme ID in the URL. If you already have a theme configured, use this Theme ID instead.

Enter Shopify Theme ID from URL

Note: Although the default theme – “Debut” – is a fully functional coded theme, we are going to overwrite it with our code.

Step 3: Configure the theme kit

Theme kit is a command line tool for creating and managing Shopify themes. In this tutorial, we’ll be using Theme Kit to monitor code changes in our theme directory and deploy those changes to our theme.

Theme Kit works on Windows, macOS, and Linux, and works with workflow tools like Git and Node.js. To keep things simple enough, we’ll skip the workflow tools and just use Theme Kit.

Install the theme kit

First, install Theme Kit using the command line.

Windows and Chocolate

choco install themekit

macOS and Homebrew

brew tap shopify/shopify
brew install themekit


curl -s | sudo python

Create a Shopify “app”

Next, create a Shopify “app” to acquire the necessary credentials that the theme kit needs in order to authenticate the theme changes.

In the Shopify admin, go to applications > Manage private apps, then check all three boxes to agree to the terms and conditions. Then select Activate the development of private applications > Create a private app and fill out the form.

In this step, you will need to give your private app a name and enter an emergency developer email address. You will also need to enable “Read & Write” access for “Themes” before clicking the button. to save button. This last point is hidden behind a View inactive Admin API permissions scrolling menu.

Create a private Shopify app

Finally, click Create an app and write down the “Password” on the next screen.

Watch for code changes

With the theme kit installed and our Theme ID and Password ready, we need to run the watch command from the command line.

First, CD in your theme directory.

Then run the following commands to open the theme in your browser and watch for code changes. Remember to replace xxx with your myshopify URL (minus the https://), with your password, and with your Shopify theme ID:

theme open -s -p <password> -t <theme-id> --hidepb
theme watch -s -p <password> -t <theme-id> --allow-live

Note the additional indicators:

  • --hidepb: hide the boring Preview bar
  • --allow-live: some understandable friction to let you know you’re editing the theme live (in case you didn’t!)

I would suggest running the above command sequence as Alfred workflow (or similar) for convenience. While you can store the theme’s credentials in a config.yml file, I wouldn’t risk exposing them accidentally – for example, via GitHub (which would be a security hole).

And with that done, let’s dive into the code side of things.

Step 4: Create the theme wrapper (theme.liquid)

We will start with theme.liquid file, because not only does it have specific requirements, but it is one of the most important files in a Shopify theme. Simply put, this file is the theme’s wrapper: whatever is marked in theme.liquid will appear on each page. You’ll want to start the markup like this:

<!doctype html>
    <!-- head markup -->
    {{ content_for_header }}
    <!-- header markup -->
    {{ content_for_layout }}
    <!-- footer markup -->

You probably noticed in the code above that to produce something with Liquid you will need to use double braces ({{ }}). On that note, there are two things that have already been released. These are required, and the theme kit will generate an error if any of them are missing from your theme.liquid:

  • {{ content_for_header }}: a code injection of everything needed to make features like Shopify Analytics work
  • {{ content_for_layout }}: inject the relevant model (for example blog.liquid), which are all stored in /templates

Remember that Theme Kit is watching you. Every time you save your file, Theme Kit will know and deploy the changes to your remote theme (although you will need to refresh your browser to see them).

Step 5: Loop over the items (blog.liquid)

In this next step, we’ll dive into blog.liquid and browse all of our articles. If you haven’t created one yet, go to Online Store > Blog posts and create a blog with a few articles, not forgetting to set their visibility on visible (the default is hidden).

You will find the said blog on The default Shopify blog is at /blogs/news/.

Paste the code below in blog.liquid will list all the posts in the current blog, displaying the title of each one wrapped in a element that refers to the article concerned:

{% for article in blog.articles %}
  <a href="{{ article.url }}">{{ article.title }}</a>
{% endfor %}

Further reading:

Step 6: Check out the article (article.liquid)

In this step we will write the code for article.liquid. This will display the article, but if the user is not a connected customer, paying, it will be blurry and a Have access the button will take the user to /cart/ (and after that, the checkout).

Create a “product”

First, we’ll need to create a “Product” that offers blog access for a one-time fee (Shopify can do this natively) or on a subscription basis (Shopify subscription app obligatory).

Move towards Some products > Add a product and name it something like “Premium Blog Access”. Of course, be sure to uncheck the box Track quantity and the This is a physical product checkboxes.

Create a Shopify product

Click on to save then write down the product ID from the URL.

Pre-write logic

Use the following code to check if the “item” is already in the cart, replacing “ID” with your product ID. We will verify the existence of the accessInCart variable later to ensure that users cannot accidentally add the item to cart twice:

{% for item in cart.items %}
  {% if == "ID" %}
    {% assign accessInCart == "y" %}
  {% endif %}
{% endfor %}

Likewise, use the following code to check if the client (assuming it is logged in) already has access. We will verify the existence of the hasAccess variable later to ensure that connected clients do not see the Have access button or be prevented from viewing content.

Again, don’t forget to replace “ID” with your Product ID:

{% if customer %}
  {% for order in customer.orders %}
    {% for line_item in order.line_items %}  
      {% if == "6816002113696" %}
        {% assign hasAccess == "y" %}
      {% endif %}
    {% endfor %}
  {% endfor %}
{% endif %}

To make the code a little more SEC (don’t repeat yourself), include these two snippets in theme.liquid if you want to include a Have access button elsewhere than article.liquid. Put the snippets in theme.liquid ensure that the accessInCart and hasAccess variables can exist in all /templates.

Note: You will also want to include the following: “Is the client logged in or not?” »Logic in theme.liquid so customers can sign in or sign out from any page or template:

{% if customer %}
  <a href="/account/logout/">Logout</a>
{% else %}
  <a href="/account/login/">Login</a>
{% endif %}

Exit the article

Then the following code will display the article but add a .blurred class if the client does not have access to the blog (or is not logged in and therefore access cannot be verified):

<article{% unless hasAccess %} class="blurred"{% endunless %}>
  {{ article.content }}

Include the following code in your CSS to enable blurring:

.blurred {
  opacity: 0.5;
  filter: blur(0.5rem);
  user-select: none; // Prevents text selection
  pointer-events: none; // Prevents click events

As a bonus, you may want to use JavaScript cookies or localStorage allow reading of [x] items, then apply the above .blurred class only after these articles have been read. This improves SEO by allowing articles to be indexed and improves conversions by providing limited access.

Create a “Get access” button

Finally, here is the Have access logic and markup of buttons:

{% unless hasAccess %}
  <a href="/cart/{% unless accessInCart %}add/?id=ID&return_to=/cart/{% endunless %}">Get access</a>
{% endunless %}

Again, don’t forget to replace “ID” with your Product ID.

Further reading:

Step 7: Build the rest of your theme

Alas, the last step is the one you will have to take on your own: build the rest of your theme. In step 1, we created a few .liquid files in /templates. Some of them (for example login.liquid and cart.liquid) are essential for maintaining the “Premium Blog Access” functionality.

Consult the official Shopify Themes Documentation, which will walk you through not only the basics of creating a Shopify theme, but also each individual .liquid model (here is sample code for login.liquid, for example).

Enjoy developing the rest of your Shopify theme!


Leave A Reply