# Sections and blocks

> Change a Shopify section's settings from midcode's right panel, add, hide, move and remove sections and blocks, and see what each one writes in the theme's JSON.

- Page: https://midcode.app/docs/shopify/sections
- From the midcode docs. Every page as Markdown: https://midcode.app/llms.txt
- Status: This ships with the next release of midcode. The version you can download today (1.1.2) doesn't have it yet.

In a Shopify theme a page is a list of sections, and each section has settings and blocks. Which settings a section has is declared in its `{% schema %}` (`sections/<type>.liquid`). Their values, and which sections a page has in which order, are kept in JSON: the page's template (`templates/index.json`) or a section group (`sections/header-group.json`).

Shopify's theme editor changes that JSON from its sidebar. midcode does the same from its right panel, as edits to the files in your folder: the smallest change that says it, undoable, and listed in Publish. To open a theme in midcode, see [Shopify themes](https://midcode.app/docs/shopify/themes.md).

## The Section panel

In a theme, the right panel has a group named "Section".

- With an element [selected](https://midcode.app/docs/editor/select-move-resize.md), it shows the section that element belongs to.
- With nothing selected, it shows the page's sections, starting on the first one of the template.

The "Section" list at the top has every section of the page in the order it's drawn: the section groups above the page (the header), the template's own sections, then the footer's group. Each one says which file it's in (`index`, `header-group`), and a hidden one is struck through. Pick one to see it without selecting anything on the canvas. "Shopify's editor", beside the title, opens the store's themes in Shopify's admin.

### How the section is found

Shopify wraps each section of a page in an element whose id carries the section's key in the JSON (`shopify-section-template--…__image_banner`). When the selected element sits inside one, that key is the section.

When it doesn't, the file the element is written in names the type (`sections/image-banner.liquid` is `image-banner`), and the page's first section of that type is taken. If the page has two, pick the other in the list.

The template comes from the page's address: a product page reads `templates/product.json`, the home page `templates/index.json`. An element written in `layout/theme.liquid` belongs to no section, and the panel doesn't show for it.

## Settings

The panel shows each setting of the schema with the control for its type. Labels come from the schema, and a `t:` label is read from `locales/en.default.schema.json`. A setting with no value in the JSON shows the schema's `default`.

| Setting type | Control |
| --- | --- |
| `text`, `url`, `inline_richtext`, any type not listed here | A text field |
| `textarea`, `richtext`, `html`, `liquid` | A field of several lines. Rich text is edited as its HTML (`<p>…</p>`) |
| `number` | A field that takes a number |
| `range` | A slider with the schema's `min`, `max`, `step` and `unit` |
| `checkbox` | A switch |
| `select`, `radio` | A list of the schema's options |
| `color`, `color_background` | A field for the value, with its swatch |
| `color_scheme` | A list of the theme's color schemes (from `config/settings_data.json`) |
| `image_picker`, `product`, `collection`, `page`, `blog`, `link_list` | Picked from the store (below) |
| `header`, `paragraph` | Words to read: nothing to set |
| `video`, `product_list`, `collection_list`, `article`, `font_picker`, `metaobject`, `metaobject_list` | Shown, not changed here |

A typed value is written when you leave the field (or press `Return` in a one-line field), a slider when you let go, a switch or a list at once. In the trial on a development store the preview showed a setting about a second and a half after it was written.

The last row is what midcode has no picker for yet. The panel shows what's picked and says "Picked from the store: changed in Shopify's editor for now."

## Things from the store

A setting that points at something of the store opens a picker: `image_picker` (an image of the store's files), `product`, `collection`, `page`, `blog` and `link_list` (a menu). Click the field and type in "Search the store". "None" clears the setting.

For an image, the list has the store's images, newest first, and "Upload an image…", which puts a file of your Mac into the store's files (JPG, PNG, WebP, GIF, AVIF or HEIC, up to 20 MB) and picks it.

The picker reads the store through its Admin API, so the store has to be connected. When it isn't, the picker says so and offers "Open the Store view to connect it": see [Connect the store](https://midcode.app/docs/shopify/store.md).

What's written is what a theme keeps, not the thing itself:

| Picked | Written in the JSON |
| --- | --- |
| A product, a collection, a page, a blog | Its handle: `"linen-shirt"` |
| A menu | Its handle: `"main-menu"` |
| An image | `"shopify://shop_images/hero.jpg"` |

> [!NOTE]
> An uploaded image is in your store from that moment. `⌘Z` takes back the setting, not the upload.

## Add, remove, hide and move sections

The buttons under the "Section" list act on the section that's shown.

- **"Move up" / "Move down"** move it among the sections of its own file. A section of the template doesn't move into the header group.
- **"Hide this section"** keeps it in the theme and stops the page from drawing it. "Show this section" brings it back.
- **"Remove this section"** takes it out of the file. Nothing asks first: `⌘Z` brings it back.
- **"Add a section"** lists the kinds the theme lets you add there. The new one goes right after the section that's shown, with the blocks and settings of its first preset, and the panel moves to it.

A kind of section can be added when its file in `sections/` has `presets` in its schema, and its `enabled_on` and `disabled_on` don't close the template or the group you're in. In older themes the schema's own `templates` list is read the same way.

## Blocks

Under the settings, "Blocks" lists the section's blocks in order, each with its name and its first text. Click one to open its settings, which use the same controls. The buttons on its row are "Move up", "Move down", "Hide this block" (or "Show this block") and "Remove this block".

"Add a block" lists the block types of the section's schema that still fit: a type under its own `limit`, while the section is under its `max_blocks` (50 when the schema doesn't say). The new block goes last, with the settings its type has in the section's first preset, if any.

## What midcode writes

Every change is made to the JSON as text, on the lines it touches. The comment Shopify puts at the top of the file stays, and so does the rest of the file, byte for byte. The examples are from a home page, `templates/index.json`.

### One value

```diff title="templates/index.json"
       "settings": {
-        "image_overlay_opacity": 40,
+        "image_overlay_opacity": 60,
         "image_height": "large"
       }
```

A setting that had no value yet is one new line, last in `settings`, indented like its neighbours:

```diff title="templates/index.json"
       "settings": {
         "image_overlay_opacity": 60,
-        "image_height": "large"
+        "image_height": "large",
+        "show_text_box": false
       }
```

### A new section

The section gets a key made the way Shopify's editor makes them: its type and six letters and digits. Its entry goes into `sections` after the one it follows, and its key into `order`.

```diff title="templates/index.json"
     "image_banner": {
       "type": "image-banner",
       "settings": {
         "image_overlay_opacity": 60
       }
     },
+    "rich_text_Xk3mPq": {
+      "type": "rich-text",
+      "blocks": {
+        "heading_a8FjkL": {
+          "type": "heading",
+          "settings": {
+            "heading": "Talk about your brand"
+          }
+        },
+        "text_Tn4GhR": {
+          "type": "text",
+          "settings": {
+            "text": "<p>Share information about your brand.</p>"
+          }
+        }
+      },
+      "block_order": [
+        "heading_a8FjkL",
+        "text_Tn4GhR"
+      ],
+      "settings": {}
+    },
     "featured_collection": {
```

```diff title="templates/index.json"
   "order": [
     "image_banner",
+    "rich_text_Xk3mPq",
     "featured_collection"
   ]
```

A new block is written the same way: its entry last in the section's `blocks`, its key last in `block_order`.

### Hidden

```diff title="templates/index.json"
     "featured_collection": {
       "type": "featured-collection",
+      "disabled": true,
       "settings": {
```

Showing it again takes that line out. A block is hidden the same way, inside its own entry.

### Moved

Only `order` changes (`block_order` for a block). The list is written again whole, one key per line, as Shopify writes it.

```diff title="templates/index.json"
   "order": [
     "image_banner",
-    "rich_text_Xk3mPq",
     "featured_collection",
+    "rich_text_Xk3mPq",
     "collage"
   ]
```

### Removed

The section's entry leaves `sections` and its key leaves `order`. Adding a section and then removing it leaves the file exactly as it was.

Before saving, midcode reads the result back as Shopify would. If it couldn't be read, nothing is written and midcode says it can't read the file right now.

## Undo and Publish

Each change is one edit: `⌘Z` undoes it, and [Publish](https://midcode.app/docs/publish/publish.md) lists it by what it was ("Add a section (index.json)", "Hide a section (index.json)"). Like every edit in a theme, it reaches the development theme through the Shopify CLI. It reaches your other themes when you send the theme: see [Send the theme to your store](https://midcode.app/docs/shopify/themes.md).

## Limits

- Tried with Dawn's files, and live on a development store: the section is found from the page's real ids, and a setting written, a section added, hidden or removed showed on the storefront in about a second and a half. The pickers were tried with that store's real files and products.
- Only JSON templates and section groups. A section a layout includes by name (`{% section 'announcement' %}`), whose values are in `config/settings_data.json`, isn't in the panel. A template written in Liquid (`templates/page.liquid`) has no sections to list.
- Theme settings, the ones Shopify's editor has under "Theme settings" (colors, fonts), are not in the panel.
- The default template of each kind of page is read. A product assigned to `templates/product.featured.json` still shows the sections of `templates/product.json`.
- App blocks (`@app`) and theme blocks (`@theme`, the files in `blocks/`) can't be added. A theme block that's already in a section shows with "Nothing to set in this block.", and blocks nested inside a block aren't listed.
- A color is typed, not picked.
- Setting types in the last row of the table are changed in Shopify's editor.
