Skip to main content
ASoc
Tutorial

Online Store 2.0 in Next.js: Sections, Templates and the Missing Editor

Shopify's four Online Store 2.0 ideas mapped to a shipped Next.js codebase: 33 organisms, typed metafield-style fields, one 14.8 KB stylesheet, and the editor you cannot port.

The ASoc Team8 min read

Online Store 2.0 is Shopify's 2021 theme architecture: every page is built from reorderable sections, page layouts live in JSON templates, apps appear as blocks, and structured data lives in metafields. A Next.js storefront has an equivalent of each part — except the one that matters most to a merchant, the visual editor.

We sell Next.js templates and do not run on Shopify, so this is not a how-to-upgrade guide. It is the inverse question: which of Online Store 2.0's ideas can you reproduce in a code-first storefront, what does each cost, and which one can you not? The answers below come from this repository, a 92-component Next.js 16 site, rather than from a theme.

What Online Store 2.0 changed, in four parts

Shopify's documentation and the agency write-ups on it describe the same four headline features. The vocabulary is worth fixing before comparing anything:

Online Store 2.0 conceptWhat it does for a merchant
Sections on every pageReorder and add page blocks on any page, not just the home page
JSON templatesA page's layout is data (a list of sections and their settings), not a Liquid file
App blocksThird-party apps appear as draggable blocks, with no code pasted into the theme
MetafieldsTyped custom fields on products and other objects, editable in the admin

The architectural idea underneath all four is one move: separate what a page contains from the code that renders each piece. Everything else follows from it. That move is not Shopify-specific, and it is how this repository is already organised.

The same idea in this codebase

Online Store 2.0Equivalent hereWhere
SectionAn organism — one page section that owns its own shellsrc/components/organisms/ — 33 of them
JSON templateA template component that only orders organismssrc/components/templates/ — 11 of them
Section settingsA typed data array the organism maps oversrc/data/ — 15 files
MetafieldsTyped fields on the catalog's product recordTemplateProduct in src/data/catalog.ts — 17 fields
Theme editorNone—

The home page is the clearest example. This is the whole template, copied from src/components/templates/HomeTemplate.tsx:

export default function HomeTemplate() {
  return (
    <>
      <Header />
      <main id="main">
        <Hero />
        <FeaturedTemplates />
        <TechStack />
        <Features />
        <FeatureTabs />
        <UseCases />
        <Testimonials />
        <Blog />
      </main>
      <Footer />
    </>
  );
}

Eight sections between a header and a footer, in an order a person decides. A Shopify index.json is the same list with a settings object attached to each entry. The difference is where the list lives: Shopify keeps it in a file the editor can rewrite; here it is TypeScript, so reordering is a commit and a deploy.

Our rule file states the contract the way OS 2.0 states it for sections. A template "holds no content", an organism "owns its <section>/<header>/<footer> shell", and a level "may only import from the levels below it". That last clause is what keeps a section reusable on any page, which is the property Shopify's "sections on every page" was introduced to deliver. The full pattern is written up in atomic design in Next.js components.

Metafields are the part that transfers best

A metafield is a typed, validated field you attach to a product. The code-first equivalent is a field on a TypeScript interface, and it is stricter than a metafield because the compiler and the test suite both enforce it.

TemplateProduct in src/data/catalog.ts has 17 fields across 111 product pages, from slug and seoLabel to gallery and changelog. One of them exists because of a defect, and the defect is the best argument for typed fields we have.

In August 2026 Search Console showed 111 product pages and 7 impressions between them. The cause was that every page's title was built from the product's invented brand name (ASoc Haven), which nobody searches for. The fix was a new required field, seoLabel, that says what the product is in the words a buyer types — and a test that makes the field impossible to get wrong:

it("every product has a unique, well-formed seoLabel", () => {
  const labels = catalog.map((p) => p.seoLabel);
  for (const p of catalog) {
    expect(p.seoLabel, `${p.slug} missing seoLabel`).toBeTruthy();
    expect(p.seoLabel, `${p.slug}: "${p.seoLabel}"`).toMatch(/Template$/);
    expect(p.seoLabel.length, `${p.slug}`).toBeLessThanOrEqual(50);
  }
  expect(new Set(labels).size, "duplicate seoLabel").toBe(labels.length);
});

A Shopify metafield definition can mark a field required or constrain its type. It cannot express "unique across all 111 products and no longer than 50 characters", and it cannot fail a deploy when a merchant breaks the rule. That is the real trade: a metafield gives a merchant freedom; a typed field with a test gives the site a guarantee. Which you want depends on who is editing.

App blocks have no equivalent, and that is mostly the point

App blocks exist so a merchant can add a reviews widget without touching theme code. There is nothing to port: this site has no app ecosystem. Its 13 production dependencies include no review, loyalty or popup scripts, and the output is correspondingly small — the whole site ships as one stylesheet of 83,232 bytes (14,835 gzipped), measured from .next/static/chunks after npm run build.

On a themed store, the performance ceiling is set by what apps inject. Here it is set by us. Shopify advantages, priced in code counts what it costs to give up the ecosystem: 1,545 lines of TypeScript and 271 lines of SQL for a subset of what Shopify provides.

The missing piece: the editor

Everything above reproduces OS 2.0's structure. None of it reproduces the thing merchants actually use it for: changing a page without a developer.

On this site, moving Testimonials above Features means editing HomeTemplate.tsx, opening a pull request, waiting for CI (lint, format, tests and a full build) and merging. That is a fine workflow when the person doing it writes code. It is the wrong one for a marketing team that wants to reorder a page on a Tuesday.

You have three honest options:

  1. Accept it. If developers own the pages, the typed-template model is cleaner than any editor and easier to review.
  2. Add a headless CMS that stores the section list as data, and make the template map section names to organisms. You gain an editor; you take on a schema, previews and a second system that can drift from the components.
  3. Stay on Shopify, or go headless with it, if non-developers editing layouts is the requirement. Shopify vs a Next.js storefront covers when that is the right call.

We run option 1. We would not claim it generalises.

Troubleshooting a section-based architecture

SymptomLikely causeFix
A section only works on one pageIt imports page-specific data directlyPass content in as props; keep data files at the organism level
Organisms import each otherThe levels are not being enforcedCompose only upward; a lower level never imports a higher one
Page titles are all the brand nameNo typed "what this is" fieldAdd a required field and a uniqueness test, as seoLabel does
A content edit breaks the buildThe type system caught a missing fieldThat is the feature; fix the data, not the type
Marketing wants to reorder sectionsNo editor in a code-first stackOption 1, 2 or 3 above — decide who owns layout
New tokens do not appear in devTailwind v4 + Turbopack does not hot-reload @themeRestart npm run dev after editing globals.css

Frequently asked questions

What is Shopify Online Store 2.0? Shopify's theme architecture, introduced in 2021. It lets merchants add and reorder sections on any page, defines page layouts in JSON templates, lets apps appear as blocks, and adds native metafields for custom product data.

Do I need Online Store 2.0 to use a theme editor? On Shopify, the editor features apply to themes built on the new architecture; Dawn is Shopify's reference theme for it. Whether an older theme gets them depends on the theme, so check before assuming.

Can a Next.js site do what Online Store 2.0 does? Structurally, yes: sections map to components, JSON templates to ordered component lists, metafields to typed fields. What it does not give you out of the box is the visual editor, which needs a headless CMS or a developer.

Is a typed field better than a metafield? For a site a developer maintains, usually — it is validated at compile time and by tests. For a store a merchant maintains, no: a metafield is editable without a deploy, and that is what they need.

If you want the section architecture without building it

The structure above — organisms ordered by a template, content in typed data files, one static stylesheet — is what the Next.js landing page templates and Tailwind landing page templates ship with. For the shop-shaped version of the same question, start with Shopify vs a Next.js storefront.

Templates in this post

ASoc Beacon, ASoc Beaker and ASoc Blueprint are Next.js + Tailwind landing page templates built on the same organism-and-template structure described above.

Keep reading

Tutorial12 min read

Automated Product Screenshots with Playwright, 111 Templates Deep

The capture is four lines; deciding what is in frame is the work. Nav-driven page discovery, the is-this-the-product check, and the proxy bug that blanks every Chromium request.

Read more
Tutorial10 min read

A Podcast Landing Page Is a Registry, a Feed, and One CSP Line

Episodes belong in a typed registry, the feed is the actual product, and the player embed renders blank unless your Content-Security-Policy names its host.

Read more
Tutorial13 min read

Programmatic SEO in Next.js: Derive the Pages, Don't List Them

A hand-maintained slug list left 24 of our products on no category page at all, and nothing failed. Here is the derived hub-and-spoke build that fixed it.

Read more