---
title: JSON Editing
published: true
index: 0
---

# Shopify JSON Editing Workflow

## Overview

Edit `templates/*.json`, JSON section data, `config/settings_data.json` and `config/settings_schema.json` using the target theme's existing types and schemas. Treat Liquid schemas as read-only. If a design needs new types or non-JSON code, explain the gap and propose the closest supported result.

## When to use

Use for JSON templates, including alternate templates; existing theme-block composition; global settings definitions/values; and layout, content, color, typography, spacing, visibility or behavior exposed by existing schemas. Visual references may guide the closest JSON-supported composition.

## When not to use

Exclude checkout branding/extensions, app extension code, Liquid templates, new sections/blocks/snippets, assets, JavaScript, CSS and Liquid-schema edits. Do not create files under those code paths. If a build generates JSON, read project guidance and edit its JSON/settings source of truth; non-JSON source work is outside this skill.

## Quick start

1. Understand the request and discover valid types and parent-child edges.
2. Inspect optional matching examples, schemas and global design settings; build a setting-constraint ledger.
3. Compose JSON using valid types, settings and ordering.
4. Resolve a verified preview through `$preview-shopify-theme`, preserving source/store/theme and process identity.
5. Inspect the edited routes at desktop/mobile widths and correct mismatches.
6. Parse/schema-validate locally; perform strict upload validation only when the real upload is authorized.

## Workflow

### Step 1 — Understand user requirements

Extract layout, columns/rows, content types, hierarchy, spacing, alignment, colors and responsive intent from text or images. Static images do not establish exact breakpoints, font sizes or pixel spacing; name that uncertainty.

**Design images and mockups**

- Infer section structure, stacking order, media placement and qualitative spacing from screenshots/Figma exports. Verify all Shopify types, keys and enum values against the target theme.
- For full-page or brand-specific work, inspect global typography, palette, schemes/gradients, buttons, radii, borders and spacing first. Skip global changes only for explicit template-only work or globals that already match.
- Use source images only to locate media blocks. Do not copy, crop, recreate, download, generate or invent assets from a mockup. Leave valid image/media settings blank unless the user supplies existing asset filenames, Shopify references, selected settings or files explicitly intended for storefront use.
- Report details requiring arbitrary typography, CSS, markup or new behavior as theme-code gaps; deliver the closest existing schema-supported structure.

### Step 2 — Discover allowed block types

Do this before emitting any `type`:

1. List `blocks/`; confirm each basename/type in the target schema.
2. Read `{% schema %}` for every section and nested parent block. Validate **each immediate parent-child edge**. Existing content blocks may need an allowed wrapper rather than direct nesting.
3. Treat explicit `blocks` arrays as allowlists. `@theme` permits general theme blocks; specific lists permit only their listed types and any listed `@app`. Resolve template section types through `sections/<type>.liquid`.
4. `_`-prefixed block types may be private/static even with presets. Before nesting one under `@theme`, verify precedent in target templates/presets; parents may need explicit declarations. Never modify Liquid to allow it: choose another valid block or report the gap.
5. Use only the resulting allowed types. Copy a working target pattern or suggest the closest existing type when the requested layout is unavailable.

### Step 3 — Check bundled examples (optional)

Follow [Choosing the best example to reference](examples/catalog.md): compare the theme name, guide and block basenames, then open at most one matching example. If none fits, use target templates. Every copied type/setting still needs target-schema verification.

### Step 4 — Map requirements to real blocks

Choose layout/content blocks from the allowed set. Map template-level sections to existing section files. Use scoped Jevgrep questions when available, verify actual excerpts/files/schemas, and use direct reads/`rg` for exact matches or fallback. Do not install search tools or request credentials.

### Step 5 — Analyze block and section schemas

Read each `{% schema %}` for allowed children, settings, defaults and presets. Build a parent-child map for every emitted nesting level.

### Build a schema settings ledger before writing JSON

Record every global, section and block setting you will emit:

| Setting | Required check |
| --- | --- |
| `range` | Record `min`, `max`, `step`; use an in-bounds `min + (N * step)` for whole-number `N`. For min 10/step 2, use 14 rather than 13; min 100/step 5 permits 155 or 160, not 158. |
| `select` | Use an exact `options[].value`, never an invented CSS-like value. |
| Typed settings | Match JSON types for `checkbox`, `number`, `text`, `richtext`, `image_picker`, `url`, `collection`, `product`, `blog` and `page`. |
| `visible_if` | Hidden values may still fail upload. Omit inactive custom-only values or validate their range/select constraints. |

Consult the selected theme example for upload-specific traps; copied settings still need validation against their destination type.

### Run a global settings pass for new pages and mockups

Before composing a new or heavily revised page, read `config/settings_schema.json` and active `current`/`color_schemes` in `config/settings_data.json`. Compare body/heading fonts, base size, scale, line heights/case, button typography, foreground/background/button/link/overlay colors, gradients, radii, borders, margins and gaps.

Update mismatched globals unless the user requests template-only work; record why matching globals remain unchanged. Prefer responsibility in this order:

1. **Global:** brand typography, palette, named schemes, gradients, buttons, radii, borders and spacing defaults.
2. **Section:** composition, scheme assignment, width, margins, alignment and behavior.
3. **Block:** intentional local exceptions, visibility and display-heading art direction.

Use default typography tokens for ordinary body, label, button and product-card text. Reserve custom block sizes for intentional display headings or requested exact local art direction. Prefer complete named color schemes over repeated overrides; mirror the active data shape and use schema-supported assignment settings such as `color_type: "custom"`/`color_scheme_custom` only when present.

### Step 6 — Apply theme design controls

- Use schema-defined settings. A `custom_css` setting is allowed only when already exposed and explicitly requested. Its entries must be complete selector rules, such as `.rte { text-transform: uppercase; }`; never standalone declarations or stylesheet edits.
- Global definitions belong in `settings_schema.json`, active values in `settings_data.json`. Preserve `current` structure, group conventions, IDs, types, defaults/options and complete scheme objects. Add no arbitrary tokens/classes or non-JSON behavior through schema changes.
- Use section/block settings for a contained change that should not affect the whole store. Validate every destination key, type, range, select and enum-like value; a setting valid on one block may be invalid on another.
- Respect parent inheritance; override local color/type/borders only when the design needs it and the schema supports it. Verify restricted container children and nesting against the same target theme or a verified matching example.

### Step 7 — Compile JSON structure

Follow Shopify's JSON shape and applicable project rules, including `.cursor/rules/templates.mdc`, `blocks.mdc` or `schemas.mdc` when supplied.

**Template structure:**

```json
{
  "sections": {
    "<sectionId>": {
      "type": "<sectionType>",
      "settings": {},
      "blocks": {
        "<blockId>": {
          "type": "<blockType>",
          "name": "t:blocks.block_name",
          "settings": {},
          "blocks": {},
          "block_order": []
        }
      },
      "block_order": ["<blockId>"]
    }
  },
  "order": ["<sectionId>"]
}
```

**Block instance IDs:** use descriptive role prefixes matching target conventions, adding a unique suffix when needed. Instance IDs cannot start with `_`, even when private block **types** do; use `grid_products_best` for an instance of `"type": "_grid-products"`. Keep IDs unique in template/nested scope as required.

**Static blocks and `block_order`:** declare static children in `blocks`, never sibling `block_order`. The order lists existing dynamic/reorderable siblings only; for static-only parents, use `[]` or omit it when the target pattern permits. Top-level `order` lists the sections to render.

Use actual layout settings and the theme's color/spacing system. Follow its translated block-name convention, such as `"t:blocks.image"`.

**Whole-template replacement guard:** strip Shopify's generated-file comment header, parse and verify exactly one top-level object; never append old template content after the closing brace.

```sh
node -e "const fs=require('fs'); const s=fs.readFileSync('templates/index.json','utf8').replace(/^\/\*[\s\S]*?\*\/\s*/, ''); JSON.parse(s);"
```

**Richtext content rules:** supported tags are `p`, `h1`–`h6`, `ul`, `ol`, `li`, `a`, `br`, `strong`, `em`, `span`. Shopify sanitizes rich `text`/`richtext`; do not add `style` or inline `class` attributes. Use existing typography/richtext settings. Unsupported colored text is a theme-code gap, not permission to add inline styles, Liquid, stylesheets or assets.

### Step 8 — Preview and visually verify

Parsing, schema validation and upload success do not prove rendering or behavior. Verify every visual edit when the target preview is accessible.

#### Consume the verified preview target

Use an existing verified preview or `$preview-shopify-theme` for simulation (`references/tools/local-storefront.md`) or Shopify development (`references/tools/shopify-cli.md`). Setup verifies source, store, theme ownership, authorization, process lifetime and browser access; never infer that another development theme is safe to overwrite. Simulation needs no Shopify credentials and does not replace authorized strict upload validation.

Preserve the verified URL's preview parameters and open the exact edited route. Copy authorized JSON into its disposable theme if needed, wait for reload/sync and verify the final artifact. Pause continuing remote sync before changes outside the authorized store/source/theme scope. If unreachable or unverified, retain JSON/schema evidence and mark visual verification blocked.

#### Run the visual correction loop

1. Save and wait for successful local reload/restart or authorized sync. Rendering/upload errors fail that iteration.
2. Open the edited route, rather than only the editor, mockup, reference site or another template. Inspect desktop (for example `1440 × 1000`), mobile (`375 × 812`) and requested breakpoints.
3. Verify section/block/content/control order; loaded media with nonzero dimensions; no hidden required content; expected grid/slider columns, static/disabled containers, alignment, spacing, typography, colors, borders and buttons. Check unexpected `document.documentElement.scrollWidth` beyond `clientWidth`.
4. Exercise affected sliders, pagination, variants, add-to-cart and responsive controls.
5. Compare against the supplied reference, correct settings and repeat. Completion evidence comes from the edited target. After the final fix, recheck both viewports.

Record target/theme, route, viewports, final successful reload/sync, observations and remaining JSON-only gaps. Distinguish validation from visual verification.

### Step 9 — Validate

Reconcile every requested change with its exact file, setting/schema, parsed final value and expected rendered result. Test distinct affected routes/states at recorded viewports; name unverified assertions when the preview is unavailable. Rerun affected assertions after source/preview changes; unrelated routes/settings cannot prove a prior defect fixed.

For local-only work, parse/schema-validate and record browser evidence. State that Shopify upload validation was not performed; it is not required for a local test store.

When the real upload is requested and authorized, skip Theme Check for JSON template edits and use strict upload validation:

```sh
shopify theme push --strict --only templates/<name>.json
```

For the homepage:

```sh
shopify theme push --strict --only templates/index.json
```

These commands upload on success; they are not dry runs. Avoid interactive theme selection. If an owned `npm run dev`/`shopify theme dev` process supplies `preview_theme_id=<theme_id>`, use that verified authorized destination:

```sh
shopify theme push --strict --only templates/<name>.json --theme <theme_id>
```

Without a verified ID, ask which theme to target before pushing. Prefer existing dev logs over starting a duplicate server. Save/touch the template to trigger authorized sync; inspect `Failed to upload file "templates/<name>.json" to remote theme` and the following error, fix that error class and retry until successful sync/no new error. Treat errors after `Theme upload complete` as authoritative even with exit code `0`. Retain the exact error and add the local guard/checklist entry before retrying.

#### Validation checklist

- JSON parses as exactly one object after header removal; no appended prior template remains.
- Instance IDs are unique in scope and do not start with `_`; types may use private prefixes.
- `order`/`block_order` reference actual siblings to render; static blocks are absent from `block_order`.
- Types exist and each immediate edge is allowed; private `_` types are explicitly listed in every parent, not only covered by `@theme`.
- Setting keys/types, in-bounds range steps (including hidden values) and exact select options match destination schemas.
- Global schema/data remain aligned, including range/select/type constraints and complete color schemes. Full-page work includes a global pass or a recorded reason to leave matching globals unchanged.
- Mockup imagery remains blank unless explicit storefront assets were supplied; richtext has no inline style/class attributes.
- Final source loaded or synced to the verified preview before desktop/mobile inspection. No introduced overflow, hidden content, unloaded media or broken layout remains; affected interactions and final post-fix states were retested.
- Handoff distinguishes schema/upload validation from visual verification and names blocked evidence.

## Error handling

| Problem | What to do |
| --- | --- |
| Missing type or invalid nesting | Inspect target files and immediate parent schema; choose an existing supported type. |
| Private `_` type rejected | Verify explicit parent support; otherwise report the Liquid/schema gap. |
| `Invalid CSS value` | Use complete selector rules only in an exposed, explicitly requested JSON CSS setting. |
| Richtext style stripped | Remove inline style/class; use schema settings or report the code gap. |
| Range step/min/max error | Normalize to an in-bounds schema step, including hidden/copied values. |
| Invalid select | Use an exact schema option, never an invented CSS value. |
| Invalid block ID | Remove invalid characters/leading `_` from the instance key. |
| Static block in `block_order` | Remove it from sibling order. |
| Copied mockup imagery | Clear image values and retain valid empty media blocks. |
| Large schema | Start from a working template in the same theme. |
| Ambiguous request | Resolve the template and affected section/block instances. |
| Generated output | Edit JSON/settings source of truth only; report non-JSON source work as outside scope. |
| Existing dev process | Reuse only its verified source/store/theme/URL and upload log. |
| Ambiguous preview | Inspect existing dev output/`shopify theme info`; resolve the exact store/theme, never ambient auth. |
| Static checks pass but page breaks | Correct the edited target through the desktop/mobile visual loop. |
| Preview unavailable | Name the blocker; do not claim a visual match. |

## Further reading

- [Shopify platform reference](../tools/shopify.md): official documentation, filenames and limits.
- [Example catalog](examples/catalog.md): choose a matching bundled pattern.
- In the target repo, follow applicable `.agent/rules/templates.mdc`, `blocks.mdc` and `schemas.mdc` when present.

## Sources

Review the corresponding procedure when these official sources change:

| Shopify doc | Sections in this file |
| --- | --- |
| [Theme architecture](https://shopify.dev/docs/storefronts/themes/architecture) | Scope |
| [JSON templates](https://shopify.dev/docs/storefronts/themes/architecture/templates/json-templates) | Compilation and validation |
| [Sections](https://shopify.dev/docs/storefronts/themes/architecture/sections) | Type discovery and schemas |
| [Section schema](https://shopify.dev/docs/storefronts/themes/architecture/sections/section-schema) | Parent-child and setting validation |
| [Blocks](https://shopify.dev/docs/storefronts/themes/architecture/blocks) | Type discovery |
| [Theme blocks](https://shopify.dev/docs/storefronts/themes/architecture/blocks/theme-blocks) | Nesting and schemas |
| [Theme dev](https://shopify.dev/docs/api/shopify-cli/theme/theme-dev) | Preview verification |
| [Shopify CLI for themes](https://shopify.dev/docs/storefronts/themes/tools/cli) | Development preview lifecycle |
