Shopify Section Workflow We Use on Every Client Project
The exact section workflow Dhruv and Nishad run on every client build — from Figma handoff to theme editor QA — so merchants get editable OS 2.0 sections without rework.
Share with Shopify developers — useful guides spread faster in theme dev communities.
After 120+ client builds, Dhruv Goyani and Nishad Kikani at K2 Devworks stopped improvising section delivery. The checklist below is what runs before any module touches a JSON template — intake, conversion, schema review, and merchant handoff tuned for supplements, furniture, B2B wholesale, and DTC apparel.
If you have shipped more than a handful of Shopify themes, you already know the pain: design hands off beautiful HTML, the merchant expects drag-and-drop editing, and your deadline assumes you will not spend three hours fixing schema JSON because someone renamed a setting id. The workflow below is what we run on every client project — supplements, furniture, B2B wholesale, luxury apparel — before a single section lands on a JSON template. It is not a generic "best practices" list. It is the sequence that keeps presets visible, blocks reorderable, and CSS scoped so Dawn's header does not suddenly inherit your hero's font-size.
Phase 1: Intake — what we refuse to start without
Before opening VS Code, we require four artifacts: an approved Figma page (or HTML export) with mobile and desktop frames, a module inventory spreadsheet listing every homepage section by name, the target theme (Dawn fork, Prestige, custom), and access to a duplicate theme we can break. Missing any one of these causes rework. The module inventory sounds bureaucratic, but it is how we avoid building a "Featured grid" twice under different filenames — a mistake we still see on agency handoffs where developers hardcoded the same layout in two section files with incompatible schema ids. We map each Figma frame to a future section filename: sections/hero-split.liquid, sections/logo-marquee.liquid, and so on. Filename becomes the section type forever; changing it later means editing every JSON template reference.
Naming conventions that survive client renames
We prefix client-specific sections with a short brand slug only when the theme will contain more than twenty custom sections — otherwise plain descriptive names win. Use kebab-case, never camelCase in filenames. The type string in templates/index.json must match exactly. Internally we keep a living doc that maps Figma component names to section types so project managers do not ask us to "fix the hero" when they mean the split banner three sections down. If you are new to how section types connect to JSON templates, read How Shopify Sections Work before you name your first file.
Phase 2: Convert HTML to section scaffolding
We paste each module's HTML into the converter workspace — not because manual conversion is impossible, but because automated schema inference catches fields we would otherwise miss on a Friday afternoon. A typical hero export contains six editable surfaces: eyebrow text, heading, subcopy, primary CTA label, primary CTA URL, and background media. Manual workflows often hardcode the eyebrow. Converter output gives us a first-pass {% schema %} with typed settings and scoped CSS using section.id. We still edit every label for merchant language — "Heading" becomes "Main headline" — and we delete spurious settings the tool inferred from placeholder attributes.
Flat vs block decision at conversion time
This decision happens before schema writing, not after. If the HTML contains three or more repeating structural rows — FAQ items, testimonial cards, logo cells — we re-export in block mode or restructure the markup so repeatables share a single parent class. Shipping a FAQ with twelve hardcoded details elements is the fastest way to lose client trust. Merchants will ask to add item thirteen on launch day. Our rule mirrors Flat vs Block Sections: repeatable equals blocks, singleton equals flat settings. For block architecture details, Dynamic Shopify Blocks Guide is the reference we send junior developers.
{%- comment -%} Client FAQ — block loop skeleton we start from {%- endcomment -%}
{% for block in section.blocks %}
{{ block.settings.question }}
{{ block.settings.answer }}
{% endfor %}
{% schema %}
{
"name": "FAQ accordion",
"tag": "section",
"class": "section-faq",
"settings": [
{ "type": "text", "id": "heading", "label": "Section heading", "default": "Questions" }
],
"blocks": [
{
"type": "faq_item",
"name": "FAQ item",
"settings": [
{ "type": "text", "id": "question", "label": "Question" },
{ "type": "richtext", "id": "answer", "label": "Answer" }
]
}
],
"presets": [{ "name": "FAQ accordion", "blocks": [{ "type": "faq_item" }, { "type": "faq_item" }] }]
}
{% endschema %}
Phase 3: Schema review — the fifteen-minute audit
Every section passes a schema audit before merge. We open the {% schema %} block and check: presets array is non-empty, every visible text field in the HTML maps to a setting or block field, image tags use image_picker settings with image_url filters in Liquid, URLs use url settings not text unless there is a deliberate reason, range settings have min/max that match the CSS we wrote, and block types have human names — "FAQ item" not "block_2". We cross-reference setting types with Shopify Schema Guide when we encounter edge cases like video_url or color_scheme. Merchants do not think in ids; they think in labels. A label "Button link" paired with id btn_url is fine; id field_7 is not.
Defaults that make the theme editor demo-ready
Empty defaults make merchants think the section is broken. We seed every text setting with copy that matches the Figma placeholder, every image_picker with a theme file or Shopify generic placeholder, and presets with two block rows minimum for repeatables. When Dhruv hands off a theme for client review, the homepage should look like the approved design without the client uploading assets. This single habit reduced "the section looks empty" tickets by more than half on our last six launches. For schema theory behind defaults, How Shopify Schema Works covers the JSON mechanics.
Phase 4: Wire JSON templates — order is content
Sections do not appear on the storefront because the file exists in sections/. They appear because templates/index.json (or product.json, collection.json) references them in order. We add entries only after the section file is merged to the development theme, using stable keys like "hero_split" that do not rename when the client changes heading copy. The order array is the homepage narrative; marketing approved it in Figma for a reason. Developers who shuffle order to "test something" without syncing design cause launch-week arguments. We keep a comment in the JSON — yes, JSON with comments in our internal repo docs — mapping each key to the Figma frame number.
{
"sections": {
"announcement_bar": { "type": "announcement-bar", "settings": {} },
"hero_split": {
"type": "hero-split",
"settings": {
"heading": "Built for everyday athletes",
"button_label": "Shop collection",
"button_link": "shopify://collections/all"
}
},
"logo_marquee": { "type": "logo-marquee", "settings": {} }
},
"order": ["announcement_bar", "hero_split", "logo_marquee"]
}
Phase 5: CSS scoping and theme token alignment
Unscoped CSS is the silent killer of client themes. We wrap section styles in #shopify-section-{{ section.id }} or use {% stylesheet %} tags with the same prefix. We avoid styling bare h1 elements unless we accept that we might fight the theme's typography.css. On Dawn forks we align spacing to multiples of 0.8rem where possible and use color_scheme settings instead of hardcoded hex values when the section sits on alternating backgrounds. Nishad keeps a snippet library of spacing variables copied from the parent theme's base.css so custom sections rhythm-match without importing the entire Dawn stylesheet into every file.
When we deliberately break from the parent theme
Sometimes the design system intentionally diverges — a campaign landing with oversized display type, a wholesale portal with compact tables. We document those sections in the handoff PDF so future developers know the divergence is deliberate. We still scope selectors. The worst production bug we fixed last year was a testimonial section that set global img { border-radius: 50% } and turned product thumbnails into circles site-wide. Theme Check will not catch that. Visual regression on collection pages will.
Phase 6: Theme editor QA — our click path
QA is a script, not a vibe. Open the theme editor on iPhone width. For each new section: confirm it highlights on click, reorder two blocks and verify content moves, toggle every checkbox and select option, upload a replacement image, clear a text field and confirm empty state does not collapse layout, add a new block row, delete a block row, duplicate the section on the homepage and confirm both instances edit independently. Then repeat at 1440px width. We log failures in GitHub issues tagged theme-editor before UAT. Merchants will do everything we skip — including pasting Word HTML into richtext fields.
Phase 7: Snippets, assets, and shared logic
Not everything belongs in a section. Icon SVGs, price formatting, and card product tiles live in snippets/ and get pulled via {% render 'card-product', product: product %}. When three sections need the same star-rating markup, we extract a snippet once. Sections stay focused on layout and section.settings; snippets hold reusable logic. We also register new SVGs in the theme's assets/ folder with predictable names — icon-chevron.svg not Asset_12.svg from Figma export. For Liquid syntax refreshers during this phase, Shopify Liquid for Beginners and Shopify Liquid Cheat Sheet are what we pin in Slack during launch week.
Phase 8: Git, deploy, and client handoff
We commit one section per PR when possible so review is digestible. PR description includes a theme editor screenshot, list of setting ids, and whether the section uses blocks. Client handoff is a ten-minute Loom walking through add section, reorder blocks, and edit text — not a PDF they will not read. We mention which sections are fragile (video backgrounds, tabs with more than six panels) and which are safe for merchants to duplicate. Support retainer clients get a Notion page mapping section names to Figma components. This workflow ends when the merchant can swap a hero image without opening GitHub.
Common workflow mistakes we still fix on rescue projects
- No presets — section invisible in Add section panel on JSON templates.
- Hardcoded product handles in Liquid — breaks when merchandising renames handles.
- block.shopify_attributes missing — theme editor cannot select individual FAQ rows.
- Setting ids renamed after launch — wipes merchant content stored in theme JSON.
- Sections built on the live theme instead of a duplicate — downtime risk during deploy.
- Skipping mobile QA — block reorder handles overlap on touch screens.
Tools we keep open during every section sprint
Our dock for a typical two-week section sprint: Figma, VS Code with Shopify Liquid extension, Theme Check CLI, HTML to Liquid converter, Schema Generator for quick JSON edits, Chrome devtools device mode, and the client's duplicate theme preview URL. We do not start from blank section.liquid files except for highly dynamic app-like sections (subscription builders, complex configurators). For standard marketing modules, converter-first plus manual polish beats blank-file every time. Read Best HTML to Liquid Converter for how we evaluate tooling, and Dawn Theme Section Tutorial when the client theme is Dawn-based.
Phase 0: Duplicate theme and branch hygiene
We never build sections on the published live theme. Day one of every retainer: duplicate the production theme, name it DEV — ClientName — Month, pin the preview URL in Slack, and connect the GitHub branch that deploys only to that duplicate. Shopify CLI theme push goes to the duplicate until UAT passes. This sounds obvious until you are on a rescue call where someone edited sections/main-product.liquid on live because it was the only theme they could find. Branch naming matches section filenames where possible: feature/hero-split, fix/faq-block-attributes. One section per PR keeps review fast and lets the client approve module-by-module in the theme editor without a big-bang deploy.
Kickoff call questions that prevent section rework
We ask five questions before Figma export: Which sections must be reusable on landing pages versus homepage only? Will the client edit copy weekly or seasonally? Are there app blocks that replace custom work (reviews, subscriptions)? Which breakpoints are contractual — mobile, tablet, desktop, or wide? Who signs off on theme editor UX — marketing or operations? Answers go into the module inventory doc. When a client says they will never touch the homepage but then asks for five editable promos two weeks later, the inventory proves scope. PMs appreciate the paper trail; developers appreciate not rebuilding a hardcoded hero.
Merchant training: the fifteen-minute Loom
Handoff is not optional documentation — it is part of the workflow. We record a Loom showing: how to find the section in the theme editor, which settings are safe to change, how to reorder blocks, what happens when you duplicate a section, and which fields to leave alone (Advanced layout header). We link Section Tutorial for merchants who want self-serve depth. Clients who watch the Loom open fewer tickets than clients who receive a PDF they skim. Dhruv narrates in plain language; Nishad adds captions for accessibility. The video pays for itself the first time a merchant swaps a collection picker without pinging Slack.
The workflow is boring on purpose. Excitement belongs in the design — not in midnight schema firefights.
Putting it together on your next project
Adopt the phases in order even if your team is one developer. Intake prevents duplicate sections. Conversion with schema inference saves hours. Schema audit protects merchants. JSON template discipline preserves design narrative. Scoped CSS protects the parent theme. Theme editor QA catches what linters cannot. Snippets prevent copy-paste Liquid cancer. Handoff determines whether you get repeat business. We have used this workflow on every client project since we standardized it in 2023, and it is the reason we can quote section-heavy homepages with confidence. Start with one homepage module this week — run it through the full pipeline before building the next. Speed comes from repetition, not from skipping presets.
Frequently asked questions
Should we build sections before or after the homepage layout is approved?
Build section files as soon as individual modules are approved in Figma, but only register them on JSON templates after the full page order is signed off. We keep unregistered sections in sections/ so they are ready to drop into index.json without rewriting markup.
How many section settings is too many for merchants?
If a section has more than twelve top-level settings without headers, merchants get lost. We group controls with header and paragraph settings, push repeatable content into blocks, and hide advanced toggles behind a collapsed header labeled Advanced layout.
Do you always use blocks instead of flat settings?
No. Heroes, announcement bars, and single-column promos are usually flat sections with five to eight settings. FAQs, sliders, logo lists, and feature grids always get blocks. We decide using our flat-vs-block rule: if a merchant might add a fourth row next month, it is a block.
What is the fastest way to validate a section before client review?
Add it to a draft theme, open the theme editor on mobile and desktop, reorder blocks, toggle every checkbox, and confirm presets appear in Add section. We also run Theme Check and paste the section through our converter validator when the HTML originated from a Figma export.
How do you prevent CSS from breaking the parent theme?
Scope every selector under #shopify-section-{{ section.id }}, avoid !important unless fighting a legacy theme, and never target bare element selectors like h2 or img at the root. Dawn and Prestige both break when custom sections leak global typography rules.
Topic cluster
Shopify Sections
OS 2.0 sections, JSON templates, and section architecture.
Convert HTML to Shopify Liquid
Paste HTML & generate Liquid with schema, blocks, and scoped CSS. No signup required.
Share
Share this guide
Found this guide useful? Share it with other Shopify developers on LinkedIn, X, or Reddit.
Authors
About the authors
Practical Shopify section workflows from the developers who build and maintain this tool.

Dhruv Goyani
3 years web design + 3 years Shopify development experience
Dhruv combines web design and Shopify theme development — converting Figma and static HTML into merchant-editable OS 2.0 sections for client stores. He focuses on schema structure, section presets, and clean handoffs between design and Liquid.
Follow Dhruv on LinkedIn
Nishad Kikani
2 years web design + 6 years Shopify development experience
Nishad has six years of Shopify theme engineering — Dawn migrations, JSON templates, performance tuning, and complex block-based sections. He leads client delivery, code review, and the production standards behind every export from HTML to Liquid Converter.
Follow Nishad on LinkedInRelated articles from our team
Editorial review
Reviewed by the HTML to Liquid Converter team


Content is reviewed by the HTML to Liquid Converter Shopify development team before publication. Technical accuracy is validated against current Shopify Online Store 2.0 conventions and active client theme work.
Last updated:
Questions or corrections? Contact us.