Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 25

Schema Settings: Text, Image, Color

Recommended resources

Hello! Welcome back.

In our last lesson, we built a fully functional, dynamic mini-cart. It was a great exercise in combining Liquid, the Ajax API, and client-side JavaScript. However, our cart-drawer.liquid section was entirely hard-coded. What if a merchant wanted to change the "Your Cart" heading or the color of the checkout button? They'd have to call a developer like you. This isn't scalable or empowering for the merchant.

This lesson addresses that exact problem. We're moving from static sections to dynamic, merchant-customizable ones. Our goal is to define a section's schema using a range of input settings (text, image_picker, color). This is the core mechanism that makes Shopify themes so flexible and is a fundamental skill for any theme developer.

1. The Two Halves of a Section: Liquid and Schema

Every section file (e.g., feature-row.liquid) has two distinct parts:

  1. The Markup: The HTML, Liquid, CSS, and JavaScript that determines what the section looks like and how it behaves. This is what we've been working with so far.
  2. The Schema: A block of JSON enclosed in {% schema %} and {% endschema %} tags. This part does not render anything on the page. Instead, it acts as a configuration file that tells the Shopify Theme Customizer which settings to show the merchant.

Think of it this way: if a section is a component, the schema defines the props it accepts. The markup then uses those props to render the final output.

This image perfectly illustrates the connection: the JSON you write in the schema directly generates the input fields in the theme editor.

Shopify Section Schema to Theme Editor Visualization
This image shows how a JSON schema for a 'Featured product' section with a 'heading' setting creates a customizable 'Heading' field in the Shopify Theme Editor.

To see a quick overview of this concept, the following video explains this dual structure clearly.

How to Build Shopify Theme Sections from Scratch

Watch this short clip from Coding with Jan to solidify your understanding of the two parts of a section file.

Watch from 03:28 to 05:09. The key takeaway is understanding that the file is split into the Liquid implementation (HTML/CSS) and the JSON schema, which defines the customizer settings.


2. Anatomy of the Schema

Let's break down the structure of the schema. When you create a new section, it will have a minimal schema block. We'll build upon this.

{% schema %}
  {
    "name": "My Awesome Section",
    "settings": [
      // Input settings go here
    ],
    "presets": [
      {
        "name": "My Awesome Section"
      }
    ]
  }
{% endschema %}
  • "name": This is the user-friendly name that appears in the theme editor's "Add section" list.
  • "settings": This is an array of JSON objects. Each object in this array defines a single input field for the merchant (like a text box or a color picker).
  • "presets": This makes the section easily discoverable and addable by merchants on different pages through the theme editor. For now, just ensure it's there with a name.

Our focus today is on populating the "settings" array.


3. Defining Input Settings

Each setting object within the "settings" array has a few key properties:

  • "type": Specifies the kind of input (e.g., "text", "image_picker").
  • "id": A unique identifier for this setting. This is crucial because you'll use it to access the merchant's saved value in your Liquid code.
  • "label": The descriptive text shown to the merchant in the theme editor.
  • "default" (optional): A default value for the setting.
  • "info" (optional): Helper text to guide the merchant.

Once a setting is defined, you access its value in your Liquid markup using the syntax: {{ section.settings.your_setting_id }}.

The "Stacking Context" YouTube channel has an incredibly detailed tutorial that walks through almost every setting type. We'll use it as our primary guide. Let's start with the most basic but essential type: text.

Text Inputs: text and textarea

These are used for headings, paragraphs, and other simple text content.

Shopify Theme Development - Sections Tutorial

Let's watch how to define text-based inputs. This clip covers the standard attributes (type, id, label, default, info) that are common to most setting types.

Watch from 12:45 to 18:33. Pay close attention to: The JSON structure for a text and textarea setting. How section.settings.text_setting_id is used to print the value. The use of the newline_to_br filter for textareas to preserve line breaks.

Image Picker

This allows merchants to upload or select an image from their library.

Shopify Theme Development - Sections Tutorial

Next, let's implement an image_picker. This is fundamental for banners, product galleries, and featured images.

Watch from 39:20 to 42:30. Focus on these key points: The setting type is image_picker. You must check if the setting is blank before trying to render it: {% if section.settings.image != blank %}. The best way to render the image is using the image_url filter piped into the image_tag filter: {{ section.settings.image | image_url: width: 400 | image_tag }}. This automatically generates performant srcset attributes for responsive images.

Color Pickers: color and color_background

These settings give merchants control over the branding and style of a section.

Shopify Theme Development - Sections Tutorial

Now for the color and color_background settings. This will allow merchants to change text colors, backgrounds, and more.

Watch from 34:54 to 39:20. Note the difference between the two: color: Used for a single, solid color. The returned value is a Liquid color object, so you can access properties like .red, .green, or .lightness. color_background: Can be a solid color OR a gradient. The returned value is a CSS string, ready to be used in a style attribute.

Test your understanding!

A merchant reports that their "Featured Image" isn't showing up, even though they haven't selected one yet. Instead, a broken image icon appears. You inspect the Liquid code:

<img src="{{ section.settings.featured_image | image_url: width: 800 }}" alt="Featured image">

What is the likely cause of the broken image, and how would you fix it?

Show answer

The cause is that the image_url filter is being called on a nil (or empty) value because no image has been selected. This results in an <img> tag with an empty src attribute, which the browser renders as a broken image.

The fix is to wrap the <img> tag in a conditional statement to ensure it only renders if an image has been selected:

{% if section.settings.featured_image != blank %}
  <img src="{{ section.settings.featured_image | image_url: width: 800 }}" alt="{{ section.settings.featured_image.alt | escape }}">
{% endif %}

This ensures that no HTML is output unless section.settings.featured_image actually contains a valid image object.


4. Practice: Building a "Feature Box" Section

Let's put this all together. Your task is to create a new section from scratch called feature-box.liquid. This section will display an image, a heading, and be set against a custom background color.

Step 1: Create the file
In your theme code, navigate to the sections directory and create a new file named feature-box.liquid.

Step 2: Define the Schema
Paste the following schema at the bottom of your new file. This defines all the inputs the merchant will need.

{% schema %}
{
  "name": "Feature Box",
  "settings": [
    {
      "type": "image_picker",
      "id": "featured_image",
      "label": "Image"
    },
    {
      "type": "text",
      "id": "heading",
      "label": "Heading",
      "default": "Feature Heading"
    },
    {
      "type": "richtext",
      "id": "description",
      "label": "Description",
      "default": "<p>Use this text to share information about your brand with your customers.</p>"
    },
    {
      "type": "color_background",
      "id": "background_color",
      "label": "Background",
      "default": "linear-gradient(#ffffff, #f3f3f3)"
    }
  ],
  "presets": [
    {
      "name": "Feature Box"
    }
  ]
}
{% endschema %}

Step 3: Write the Liquid Markup
Now, add the Liquid and HTML markup above the {% schema %} tag. This code will render the section using the values from your settings.

<style>
  .feature-box-wrapper {
    background: {{ section.settings.background_color }};
    padding: 50px 20px;
    text-align: center;
  }
  .feature-box-image {
    max-width: 150px;
    height: auto;
    margin: 0 auto 20px;
    border-radius: 50%;
  }
  .feature-box-heading {
    font-size: 24px;
    margin-bottom: 10px;
  }
</style>

<div class="feature-box-wrapper">
  {% if section.settings.featured_image != blank %}
    {{ section.settings.featured_image | image_url: width: 300 | image_tag: class: 'feature-box-image' }}
  {% endif %}

  {% if section.settings.heading != blank %}
    <h2 class="feature-box-heading">{{ section.settings.heading }}</h2>
  {% endif %}

  {% if section.settings.description != blank %}
    <div class="feature-box-description">{{ section.settings.description }}</div>
  {% endif %}
</div>

Step 4: Test it!
Save the file. Now go to your theme editor (run shopify theme dev and click the customize link). On any page (like the homepage), click "Add section" and find your "Feature Box". Add it to the page and try customizing the image, text, and background. You've just empowered a merchant!


5. The Wider World of Settings

We've focused on text, image_picker, and color, but there are many more input types that allow for rich customization. The LINK video we've been using is an exhaustive reference. You don't need to memorize them all now, but it's good to know what's possible:

  • range: A slider for numeric values (e.g., setting banner height).
  • select, radio, checkbox: For predefined choices.
  • product, collection, article: Resource pickers that let merchants link to other parts of their store.
  • url: A field for any internal or external link.
  • font_picker: Lets merchants choose from Shopify's font library.

Bookmark that video. When you need to build a section and wonder, "Is there an input for...?", the answer is probably in there.


Conclusion

Today, you've unlocked one of the most powerful features of Shopify theme development. You now understand how to decouple a section's presentation from its content, giving merchants the power to customize their own storefront.

Key Takeaways:

  • A section file consists of Liquid markup for rendering and a JSON schema for defining settings.
  • The settings array in the schema contains objects, each defining one input field for the theme editor.
  • Every setting needs a type, id, and label.
  • You access a setting's value in Liquid with section.settings.your_id.
  • Always check if a setting != blank before using it to avoid errors with un-set optional fields.

In our next lesson, we will build directly on this foundation. Now that you know how to create settings for a whole section, we'll explore how to create settings for repeatable, re-orderable content within a section. We will learn to implement blocks within a section to allow for repeatable, user-generated content, such as for an FAQ, a slideshow, or a list of testimonials.