---
title: "Understanding Shopify Theme Development: Liquid for Next.js and React Developers"
slug: "shopify-theme-development-liquid-nextjs-react"
published: "2025-08-02"
updated: "2025-12-25"
categories:
  - "Shopify"
llm-intent: "reference"
framework-versions:
  - "shopify_online_store_2.0"
  - "liquid (Shopify Liquid)"
  - "next.js@15"
  - "react@18"
  - "shopify-cli@4"
status: "stable"
llm-purpose: "Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks."
llm-prereqs:
  - "General familiarity with the article topic"
llm-outputs:
  - "Completed outcome: Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks."
---

**Summary Triples**
- (templates, are, top-level pages located in /templates/*.liquid (e.g., product.liquid, index.liquid, cart.liquid))
- (sections, are, modular content blocks stored in /sections/ that include Liquid and a {% schema %} JSON block for editor settings)
- (blocks, are, repeatable components inside sections iterated via section.blocks and rendered with a for loop)
- (snippets, are, reusable partials stored in /snippets/ for smaller bits of markup shared across templates and sections)
- (assets, contain, static files (CSS, JS, images) inside /assets/ served by the theme)
- (theme_editor, enables, merchants to add, reorder and configure dynamic sections and blocks via schema-defined settings)
- (section_schema, defines, editable settings, block definitions, and default content for a section using JSON in the {% schema %} tag)
- (template_to_section, connects, templates to sections via {% section 'section-name' %} Liquid tag)
- (liquid_vs_react, difference, Liquid renders server-side templates with Shopify objects; React/Next.js render client or server components with JavaScript state)
- (making_theme_dynamic, requires, defining section settings/blocks in schema and rendering using section.settings and block.settings)
- (data_objects, include, Shopify objects like product, collection, cart, shop, and global variables (accessible in Liquid templates))
- (local_development, uses, Shopify CLI (theme serve, push/pull) and a development store for previewing theme changes)

### {GOAL}
Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks.

### {PREREQS}
- General familiarity with the article topic

### {STEPS}
1. Follow the detailed walkthrough in the article content below.

<!-- llm:goal="Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks." -->
<!-- llm:prereq="General familiarity with the article topic" -->
<!-- llm:output="Completed outcome: Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks." -->

# Understanding Shopify Theme Development: Liquid for Next.js and React Developers
> Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks.
Matija Žiberna · 2025-08-02

As someone who's spent most of my time building **[headless storefronts](https://www.buildwithmatija.com/blog/shopify-headless-vs-liquid-when-to-choose)** with frameworks like **Next.js**, I didn't take Shopify theme development very seriously until recently.

The truth is that **theme customization is much more common** than headless builds. It is faster to ship, easier to hand off to clients, and more budget-friendly. I wanted to understand how Shopify's native themes work and what it takes to customize or build one from scratch using **Liquid**.

This post breaks down the **mental model** that helped me get up to speed. If you're a frontend or full-stack developer coming from the React or Next.js world and trying to understand Shopify’s Liquid-based theming system, this is for you.

---

## The 80/20 of Shopify Themes: Start Here

Look at the high-level structure. Shopify themes are made of **templates**, **sections**, **blocks**, **snippets**, and **assets**.

Once you see how these parts fit together, you know about 80 percent of the system.

---

### Templates

* Templates are **top-level pages**.
* Each template defines the layout for one page type. This includes product pages, collection pages, cart, homepage, and others.
* Examples:
  `/templates/product.liquid`, `/templates/cart.liquid`, `/templates/index.liquid`
* Templates usually reference multiple sections.

---

### Sections

* Sections are **modular content blocks** that you can reuse and customize.
* Some sections are **static** (hardcoded), others are **dynamic** (selectable and reorderable in the Theme Editor).
* Each section lives in `/sections/` and contains Liquid code with a `{% schema %}` block.
* Example sections:
  `main-product.liquid`, `featured-collection.liquid`, `testimonial-slider.liquid`

---

### Blocks

* Blocks are **repeatable components inside a section**.
* You can use them for things like testimonials, FAQ entries, or a grid of feature cards.
* Blocks are defined inside the section's schema.
* Merchants can add, remove, or reorder them.

**Example:**

```liquid
{% for block in section.blocks %}
  <div class="testimonial">
    <p>{{ block.settings.quote }}</p>
    <p class="author">{{ block.settings.name }}</p>
  </div>
{% endfor %}
```

This is like how Payload CMS lets you define repeatable, flexible blocks.

---

### Snippets

* Snippets are reusable chunks of Liquid and HTML.
* They work much like **React components**.
* Snippets are stored in `/snippets/` and included with `{% render 'snippet-name' %}` or `{% include 'snippet-name' %}`.
* Snippets help keep code modular and clean.

---

### Assets

* These are your static files: CSS, JS, fonts, and images.
* Assets are stored in the `/assets/` folder.
* Reference them in Liquid like this:

```liquid
<link rel="stylesheet" href="{{ 'theme.css' | asset_url }}">
<script src="{{ 'app.js' | asset_url }}" defer></script>
```

You can pre-process CSS (for example, with Tailwind) or JavaScript (for example, with React) and upload the final files here.

---

## How the `{% schema %}` Block Works (and Why It Matters)

In Shopify theme development, the `{% schema %}` block lets you turn static Liquid files into **customizable components**. Merchants can then edit these through the **Theme Editor** without touching code.

In simple terms: **Schema lets you define settings and content blocks for the end user (the merchant) to control.**

You can enable editing for things like:

* Text fields (heading, subheading, button label)
* Colors, spacing, alignment, and visibility
* Repeating items (testimonials, FAQ entries, image galleries)

The schema is written in **JSON** and sits at the bottom of a `.liquid` file, inside `{% schema %}` tags.

---

### Example: A Simple Schema Block for a Section

Say you want a "Text with Image" section. Here’s a simple schema:

```liquid
{% schema %}
{
  "name": "Text with Image",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "label": "Heading",
      "default": "Welcome to our store"
    },
    {
      "type": "textarea",
      "id": "text",
      "label": "Body text"
    },
    {
      "type": "image_picker",
      "id": "image",
      "label": "Image"
    }
  ]
}
{% endschema %}
```

This will:

* Show fields for **heading**, **text**, and an **image picker** in the Shopify Theme Editor.
* Let the merchant change content visually.

Access these values in your section like this:

```liquid
<h2>{{ section.settings.heading }}</h2>
<p>{{ section.settings.text }}</p>
<img src="{{ section.settings.image | image_url }}" alt="">
```

---

### Blocks in Schema: Repeatable Content

To let a merchant add multiple items, like testimonials, you define **blocks** in the schema.

```liquid
{% schema %}
{
  "name": "Testimonials",
  "settings": [],
  "blocks": [
    {
      "type": "testimonial",
      "name": "Testimonial",
      "settings": [
        {
          "type": "text",
          "id": "quote",
          "label": "Quote"
        },
        {
          "type": "text",
          "id": "author",
          "label": "Author Name"
        }
      ]
    }
  ],
  "max_blocks": 5
}
{% endschema %}
```

Render blocks like this:

```liquid
{% for block in section.blocks %}
  <blockquote>{{ block.settings.quote }}</blockquote>
  <cite>{{ block.settings.author }}</cite>
{% endfor %}
```

This flexibility is great for both developers and merchants.

---

### Schema in Templates vs Sections

This part is important for anyone who thinks in component logic.

In a **section**, the `{% schema %}`:

* Defines fields and blocks merchants can edit
* Specifies which controls appear in the Theme Editor

In a **template**, you don’t add `{% schema %}` directly.

Modern Shopify themes, especially Online Store 2.0, use JSON for templates. JSON templates define:

* Which sections appear on the page
* Their order

**Example: `templates/index.json`**

```json
{
  "sections": {
    "hero": {
      "type": "hero"
    },
    "rich-text": {
      "type": "rich-text"
    }
  },
  "order": ["hero", "rich-text"]
}
```

This lets merchants control the page structure by adding, removing, or reordering sections. The content for sections is still defined by the section's schema.

---

## Two Ways to Add Content: Native Data and Theme Settings

Once you have the structure, your content comes from one of two places.

---

### Native Shopify Data

Shopify provides data objects, depending on page context.

For example:

* On a product page: `product`
* On a collection page: `collection`
* On the cart page: `cart`

Access them like this:

```liquid
{{ product.title }}
{{ collection.products | size }}
{{ cart.total_price | money }}
```

You do not need to fetch or import this data. Shopify adds it automatically based on routing.

---

### Theme Editor Settings (Schema)

Fields defined in the schema of your sections are editable in the Theme Editor UI.

```liquid
{{ section.settings.title }}
{{ block.settings.label }}
```

You often combine these with Shopify’s native data for dynamic, editable themes.

---

## Quick Folder Structure Recap

Here's how it fits together in files:

```
/templates/product.liquid
  └── references sections (e.g. main-product, related-products)
/sections/main-product.liquid
  └── defines blocks (e.g. features, highlights)
/snippets/
  └── reusable logic or markup
/assets/
  └── theme.css, app.js, fonts, images
/templates/index.json
  └── declares dynamic sections and their order
```

---

## Bonus: What About Tailwind or React?

You can use Tailwind or React, but you must **build them outside Shopify** and **upload as static assets**.

### Tailwind CSS

1. Set up Tailwind locally.
2. Let Tailwind scan `.liquid` files for class usage.
3. Build your `theme.css` using Tailwind and PurgeCSS.
4. Upload `theme.css` to `/assets/` and link it in your theme layout.

### React

1. Build with Vite or another bundler.
2. Output a bundled JS file (for example, `app.js`).
3. Upload it to `/assets/`.
4. Reference the script in your Liquid layout and mount to a DOM node.

I'll cover this workflow in a separate article soon.

---

## Final Thoughts

If you are coming from React or Next.js, Shopify's Liquid system can feel strange at first. Once you understand:

* Templates, sections, and blocks
* Native data vs. Theme Editor settings
* How schema ties everything together

it all becomes clearer.

This mental model helps you build dynamic, flexible, and merchant-friendly themes without overcomplication. As you get more advanced, it's easy to bring in Tailwind, React, or APIs.

Let me know if you want to see more articles about dynamic sections, metafields, performance, or deployment workflows.

## LLM Response Snippet
```json
{
  "goal": "Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks.",
  "responses": [
    {
      "question": "What does the article \"Understanding Shopify Theme Development: Liquid for Next.js and React Developers\" cover?",
      "answer": "Learn how Shopify theme development works using Liquid, explained for Next.js and React developers. Discover the structure of templates, sections, blocks."
    }
  ]
}
```