Skip to content

Shopify theme compatibility

Sellerlane implements a deliberately bounded Shopify Online Store 2.0 theme surface. Inside that boundary, compatibility means that the documented syntax, limits, URL shape, validation, and buyer-visible result are enforced and tested. Outside it, Sellerlane rejects or hides the feature instead of accepting a configuration that cannot work.

This page is the normative theme compatibility contract. It was last reconciled with Shopify’s public theme documentation and theme changelog on 14 July 2026. The broader commerce boundary is documented separately in Commerce compatibility and scope.

Compatibility status at a glance

SurfaceStatusExact boundary
Online Store 2.0 theme structureCompatibleLayout, JSON templates, sections, section groups, theme blocks, snippets, config, locales, and assets
Liquid parsingCompatible, fail closedUnknown, malformed, unclosed, deprecated, or unsupported constructs fail validation
JSON templates and section groupsCompatibleStrict schema, order, section/block limits, nesting, and static group references
Liquid objects, filters, and tagsCompatible where documentedThe Sellerlane reference is the allowlist; undocumented Shopify entries are not implied
Dynamic sourcesCompatible for documented section/block setting typesTyped picker, exact resource/closest scope, metafields, metaobjects, list projection, and save/runtime validation; no app or Markets sources
{% form %}Compatible plus typed extensionsTen portable forms and eight sellerlane_ forms; passwordless accounts and typed product data
PaginationCompatibleMaximum page size 250 and maximum reachable item 25,000; pageable list settings receive independent hashed parameters
Storefront filteringCompatible for configured product and variant metafieldsShopify parameter grammar, taxonomy category IDs, caps, page reset, and large-result suppression; standard product attributes remain unavailable
Localized storefront URLsCompatible for languagesPrimary locale has no prefix; every published non-primary locale has a lowercase prefix
Section Rendering APICompatibleCart and direct rendering return section HTML and the CSS required by the returned render tree
Standard storefront events/actionsCompatibleCurrent shopify:* browser contract with Sellerlane-owned implementation and aliases
Theme assets and CSS subsettingCompatibleStable ?v= versioning, immutable live caching, draft no-store, render-tree CSS only
Theme editor previewCompatible runtime, Sellerlane editor UISigned/revocable preview session; draft isolation; normal cart and checkout rules
Shopify apps and app blocksUnavailableNo app runtime, app embeds, app blocks, or app-provided settings
Markets and selling plansUnavailableLanguage localization only; one store currency; no subscriptions
B2B wholesaleTyped Sellerlane extensionshop.b2b_enabled, customer.b2b?, customer.purchasing_personally?, order.b2b, contextual catalog pricing, and the built-in account purchase-identity switcher; Shopify’s company/company_location Liquid objects are not implied
Deprecated LiquidUnavailableDeprecated Shopify tags and filters are intentionally not supported

Theme files and validation

A normal Sellerlane storefront theme uses:

layout/theme.liquid
templates/*.json
sections/*.liquid
sections/*.json
blocks/*.liquid
snippets/*.liquid
config/settings_schema.json
config/settings_data.json
locales/*.json
assets/*

Normal page templates are JSON so they remain editable as ordered sections. templates/robots.txt.liquid is the supported Liquid-template exception. A save, ZIP import, preview validation, or publish is rejected when a path, extension, JSON shape, Liquid program, schema, reference, or resource limit is invalid. Validation does not defer a known compiler error until a buyer opens the page.

The {% section 'name' %} and {% sections 'group' %} references are static: the name must be a quoted literal. Dynamic file lookup is rejected because it cannot be validated or safely included in the compiled manifest.

Enforced theme limits

ResourceLimit
Theme name50 Unicode characters
Files in a theme100,000
JSON templates1,000
Section groups20
Sections in one template or group25
Blocks in one section50
Effective blocks in one 25-section template/group1,250
Nested theme-block depth8
Files in blocks/300
Ordinary Liquid/code file256 KiB
JSON template512 KiB
Section-group JSON512 KiB
settings_schema.json512 KiB
settings_data.json1.5 MiB
One locale file1.5 MiB
Non-asset theme source in total250 MiB
Imported ZIP, compressed50 MiB
Imported ZIP expansion safety ceiling1 GiB
One Sellerlane-hosted theme asset20 MiB
Direct inline file transport5 MiB; larger allowed files use signed upload transport

The 20 MiB asset and 1 GiB ZIP-expansion ceilings are Sellerlane operational security limits. They do not weaken the compatible Liquid or theme structure.

Liquid compiler and runtime

Sellerlane parses Liquid strictly at the theme boundary and again at runtime as a defense in depth. The public Liquid tags, filters, and objects pages are the supported allowlists. Use the storefront filtering guide for query grammar and the data-boundary guide for the buyer-visible Drop and privacy contract.

Important behavior includes:

  • {% render %} uses an isolated variable scope and supports documented named arguments and for/with forms.
  • {% section %} renders one statically named section; {% sections %} renders one statically named section group.
  • {% schema %}, {% stylesheet %}, and {% javascript %} are file-aware and validated for their legal locations and multiplicity.
  • {% style %} can evaluate Liquid inline. {% stylesheet %} and {% javascript %} cannot contain Liquid and are collected once per source file.
  • article_list, color_palette, and standard_event_data are available on the current supported surface.
  • An unknown tag/filter, malformed expression, unclosed block, invalid schema, or deprecated construct is an error. Sellerlane does not silently echo or ignore it.
  • A storefront Liquid render has a 2-second wall-clock budget. Exceeding it terminates the render and returns an error rather than consuming an unbounded buyer request.

This follows Shopify’s stricter Liquid direction without claiming that the two engines are proprietary implementation equivalents. Portability is defined by the documented program result.

Dynamic-source contract

Section and block settings support dynamic sources for text, richtext, inline_richtext, url, color, image_picker, video, singular product/collection/page/article/metaobject resources, and their documented list forms. article_list remains a valid setting type but is not a dynamic-source target. blog is a Sellerlane-only direct-resource extension and does not imply a persisted blog_reference metafield type. Global theme settings are not connectable because they have no stable page or closest.* scope.

The seller backend owns draft persistence and metafield/metaobject definitions. The buyer preview owns the actual template, section, block, and closest.* runtime scope graph. The editor sends that snapshot-pinned graph back to the buyer datasource endpoint, and the seller independently validates the persisted expression on save. See Dynamic sources for the exact grammar, compatibility matrix, examples, limits, stale-scope behavior, and backend ownership model.

Pagination contract

Use {% paginate collection.products by 24 %} around a pageable collection. Sellerlane enforces the current Shopify storefront limits:

RuleBehavior
Maximum by value250
Maximum reachable item25,000
Invalid/non-positive pageNormalized to page 1
Page beyond the reachable rangeClamped to the last reachable page
Pageable theme-setting listsEach receives a deterministic hashed page_param
Links and anchorsExisting safe query parameters are retained; only that paginator’s page parameter changes

The independent hashed parameter prevents multiple pageable theme-setting lists from changing pages together. Ordinary resource lists use the documented page parameter; place independent resource paginators in separate sections and refresh them with the Section Rendering API when they must page independently. Pagination is implemented for collection products, blog articles, article comments, pages, customer orders, customer addresses, rewards, and the documented pageable variant surface. A product exposes at most 250 variants, and a paginated variant page is also capped at 250. variants_count reports the full supported count.

Form tag contract

The Liquid form tag reference is the complete field-level contract and includes native and Ajax examples. Supported forms are:

Portable form typeSellerlane behavior
productAdds a canonical product variant plus typed modifiers and product-type details
cartUpdates quantities and note
contactSends a contact enquiry
customerSubscribes an email address to marketing; it does not create an account
customer_loginStarts passwordless email or phone OTP sign-in
create_customerStarts passwordless enrollment
customer_addressCreates or updates an authenticated customer’s address
localizationSwitches to a published language
new_commentSubmits a blog comment with moderation/spam rules
storefront_passwordUnlocks a password-protected storefront, not a customer account

Sellerlane also provides sellerlane_otp_verify, sellerlane_cart_change, sellerlane_cart_offer, sellerlane_customer_logout, sellerlane_customer_contact, sellerlane_customer_profile, sellerlane_quote_request, and sellerlane_stock_notification.

Most portable forms use native POST/redirect/GET behavior. Two Sellerlane extensions are JSON-only today: sellerlane_customer_logout, whose script must follow the returned redirect_to, and sellerlane_customer_contact, which only starts the add-contact workflow. Contact verification is a separate JSON POST to /account/contacts/verify. Native cart-change and cart-offer redirects record form state under the base cart and product types rather than the namespaced extension types.

The canonical OTP flow keeps the identifier out of the URL by using an opaque challenge ID. The legacy challenge-less error path can still put identifier in the query string, so new themes should not use it. For ordinary contact forms, the server requires a valid email and at least one nonempty field; an HTML required attribute on contact[body] is not an independent server-side body requirement.

A form owns its action, method, encoding, CSRF input, locale prefix, trusted resource selectors, and safe return_to. return_to accepts back or a same-store relative path; external and protocol-relative redirects are rejected. All form resource IDs are reloaded in the current store before a mutation.

Product data is typed

The product form sends the selected variant in id and can send:

  • sellerlane[modifiers][MODIFIER_ID][values][], text, number, date, or file_key;
  • sellerlane[event][slot_start_utc], slot_end_utc, and an allowed host;
  • typed gift-card recipient data;
  • typed digital-delivery data; and
  • typed bundle-child selections.

Required modifiers, allowed values, selection counts, text/number/date/file constraints, price changes, inventory effects, event capacity, host rules, and product-type rules are all revalidated by the cart service. HTML required improves the buyer experience; it is never the only enforcement boundary. Arbitrary Shopify properties[...] are not persisted.

Product view/select and cart-change telemetry is emitted through the standard event contract. It is not trusted as form authority and does not replace the typed product payload.

Storefront filtering and tags

Collection and search themes should render collection.filters or search.filters and submit a normal GET form. Filter URLs use Shopify’s public parameter grammar:

SourceQuery parameterValue contract
Availabilityfilter.v.availabilityAvailable/unavailable value supplied by the filter object
Price minimumfilter.v.price.gteDecimal amount in the storefront currency’s major unit
Price maximumfilter.v.price.lteDecimal amount in the storefront currency’s major unit
Product tagfilter.p.tagMerchant tag text, preserving its stored display value
Product typefilter.p.product_typeMerchant product type text
Vendorfilter.p.vendorMerchant vendor text
Product categoryfilter.p.t.categoryExact Shopify taxonomy/category ID; __ joins a selected category subtree list
Variant optionfilter.v.option.OPTION_NAMEOption value; the option suffix is derived from the trusted filter definition
Product metafieldfilter.p.m.NAMESPACE.KEYValue allowed by the published filter definition
Variant metafieldfilter.v.m.NAMESPACE.KEYValue allowed by the published variant-owner filter definition; matching stays within one variant
Standard product attributefilter.v.t.shopify.KEYNot emitted or supported; a nonempty trusted manifest excludes it, while manifestless compatibility parsing can treat it as an ordinary variant-option key
Sellerlane product kindfilter.p.sellerlane_product_kindTyped Sellerlane extension for physical, digital, event, gift-card, and related kinds

filter.p.product_type means the merchant’s product type. It is not repurposed for Sellerlane’s internal product-kind taxonomy. The explicit filter.p.sellerlane_product_kind extension keeps portable and platform-specific semantics separate.

Filter combination and limits

  • Repeating values for a configured filter uses the operator in its trusted definition. Without a manifest, compatibility parsing also accepts the internal .all suffix as AND; themes must not emit that suffix. Different filter sources combine with AND.
  • Price bounds form one range and use the active currency exponent. A value of 10 means ten currency units, including for zero- and three-decimal currencies.
  • Applying, removing, or clearing a filter resets the relevant pagination parameter so a previously deep page cannot create an empty filtered view.
  • Each filter set, and each returned manifest, contains at most 25 filter definitions. One buyer request accepts at most 30 distinct normalized filter keys, 50 discrete values per key, and 500 discrete filter values in total. Repeated values share one key, and .gte/.lte price bounds count as one range key. These separate configuration and request limits prevent ambiguous or unbounded queries. Admin configuration prevents duplicate source definitions and uses stable order/caps for legacy rows.
  • Collection facets are suppressed above 5,000 products. Search facets are suppressed above 100,000 matching results. Product results still render; only the filter UI is unavailable for that result set.
  • Public metafield parameters are accepted only when they map to a trusted, enabled filter definition for that store. Internal definition IDs and forged namespace/key parameters are not forwarded.
  • Tags remain merchant data. The runtime does not slugify, lowercase, or replace the display value exposed by the tag/filter objects.

Localized URLs

Sellerlane supports published storefront languages without Shopify Markets. The store’s primary locale always uses the bare URL. Every published non-primary locale uses a lowercase locale prefix:

Primary English: /products/example
Published Hindi: /hi/products/example
Published English-IN: /en-in/products/example

The locale code is canonicalized as a language tag for Liquid data, while the URL segment is lowercase. Product, collection, page, blog, article, search, filter, pagination, form-action, and routes URLs retain the active published prefix. Canonical and alternate-language links use the same mapping.

POST /localization accepts locale_code (with locale and language_code as compatible aliases), requires a published locale, and redirects safely:

  • changing to the primary locale removes an existing published prefix;
  • changing to a non-primary locale replaces or adds its prefix;
  • path, query, and fragment are retained;
  • external, protocol-relative, unknown, and unpublished locale targets are rejected; and
  • an unknown locale-looking path prefix returns 404 instead of serving the primary language under a false URL.

Country/catalog and currency switching are intentionally unavailable. See Locales and translation for file fallback and schema-string behavior.

Save, compile, publish, and render

Sellerlane does not reinterpret every live theme file from mutable seller data on each buyer request. The publish path is:

  1. Validate paths, sizes, JSON, Liquid syntax, schema, references, and theme limits.

  2. Compile the complete immutable version and derive its SHA-256 manifest.

  3. Upload compiled bundles beneath the private versioned prefix _compiled/themes/v1/STORE_ID/THEME_ID/VERSION_ID/.

  4. Upload the manifest last; its presence is the commit marker.

  5. Promote the validated version to live. Buyer requests load the persisted compiled artifact and verify the manifest/hash instead of compiling mutable source at request time.

If compile or persistence fails, publish fails closed and the existing live version remains authoritative. A controlled legacy read/backfill path can migrate an older version, but production does not silently serve a half-written compiled bundle.

Compiled-artifact rollout policy

Buyer and Seller must use the same THEME_COMPILED_ARTIFACTS value. The three states are deliberately operational, not theme-facing feature flags:

ValueBehaviour
offValidate the live source, but do not require a durable compiled manifest. Use only for local development or the initial deployment step.
backfillValidate the exact live snapshot and strictly compile any older version that has no artifact. Bundles are written first and the manifest commit marker last; activation or rollback stops if that marker is still missing.
strictNever compile lazily. A missing, non-strict, malformed, or unverifiable compiled artifact blocks activation or rollback until that version is republished.

Every persisted manifest records strict compiler provenance. Runtime fallback output is never eligible for persistence, including during backfill. Compilation also bounds source reads, transforms, writes, embedded block counts, and bytes so a large but valid theme cannot create unbounded release work.

Roll out in this order: deploy the strict-capable Buyer first, deploy Seller with both services set to backfill, warm or idempotently republish every existing live version, and then switch both services to strict. Do not set Seller to strict before Buyer, and do not leave the two services on different policies.

At runtime the page context supplies live catalog/customer/cart data to the compiled theme. This preserves dynamic commerce while moving parse, schema, reference, and source-collection work out of the hot path.

Assets and CSS subsetting

Theme assets use stable content/version URLs with a ?v= parameter. A live asset is immutable-cacheable; an editor/draft asset is no-store. Themes must not add timestamps or random bare query strings for cache busting.

{% stylesheet %} content is collected by the rendered file tree. A full page ships only the CSS for sections, blocks, and snippets actually rendered. A Section Rendering API response prepends the required subset as:

<style data-section-stylesheet>
/* CSS required by this returned fragment */
</style>

That makes a section swapped into an existing page visually complete even when its stylesheet was not present in the initial document. Collected JavaScript is deduplicated by source file; theme code should still make component setup idempotent when replacing DOM.

Section rendering and cart updates

Cart add/change/update/clear and direct section-rendering requests can ask for one or several section IDs. The response returns a map of section ID to HTML. The platform renders each requested section against the requested safe same-store sections_url (or the referring page), not against untrusted page state.

The mutation happens once. The returned cart and sections describe the post-mutation state; a theme does not need to submit the same edit a second time. Replace the targeted wrappers, preserve focus where possible, and rely on the response’s section stylesheet block for newly introduced CSS. See Cart AJAX API.

Bulk cart operations are atomic and accept at most 250 lines. A mixed update can add, update, remove, change the note, and update discount codes as one server transaction. A validation failure does not leave a partially changed cart.

Standard storefront events and actions

Sellerlane installs the current standard action API under both window.Shopify and window.Sellerlane; both names point to the same Sellerlane-owned functions. The Shopify namespace is retained because imported themes legitimately call the portable contract. Internal implementation names remain Sellerlane names.

Supported event names are:

shopify:product:view
shopify:product:select
shopify:cart:view
shopify:cart:error
shopify:cart:lines-update
shopify:cart:note-update
shopify:cart:discount-update
shopify:search:update
shopify:collection:view
shopify:collection:update

The default theme emits the product-selection event when the selected variant changes; cart events after successful lines/note/discount actions; and collection/search update events after facet navigation. The standard_event_data: 'view' filter supplies canonical product, collection, or cart view payloads for the s-view-event component.

Action results expose cart.lines.nodes; browser events expose a flat cart.lines array, matching the current public contract. getCart reuses an in-flight request. configure is one-shot, requires an event target, and flushes pending events. Validation userErrors resolve as action results and do not emit cart:error; thrown transport/runtime errors reject and emit it.

Sellerlane’s first-party analytics events are separate from this portability bus. A standard event can drive theme coordination without automatically granting a pixel consent or changing server-authoritative cart data.

Preview and editor sessions

A draft preview begins with a short-lived signed token that contains the store, theme/version, and intended preview origin. The buyer service validates the signature, claims, expiry, revocation state, store/version relationship, and origin. It then establishes the preview session and removes the bootstrap token from the visible URL by redirecting to the clean page URL.

Preview responses are isolated from live caching and carry a restrictive CSP. The editor may navigate among page types and locales, but a preview never gains permission to read another store or unpublished version.

Editor interaction surface

The Sellerlane editor is behaviorally compatible for the declared section/block workflow; its React/Chakra UI is not claimed to be a pixel-identical Shopify admin clone.

Editor behaviorSellerlane contract
Current page/templateTop picker shows the active template/resource and updates after an approved preview navigation
Sidebar rowsSection/block icon or representative image thumbnail, nesting, lock/visibility state, and selection highlight
Canvas inspectionBlue hover/selection overlay maps the exact runtime section and nested block back to the left tree/right inspector
Add from canvasOverlay + opens the same section/block picker at the exact adjacent position
Picker previewsSection presets request a real draft section render when available
Add/reorder/duplicate/deleteSupported within schema, parent, depth, and count limits
Hide/showPreserves the instance/settings but excludes it from preview rendering
Removed sectionsReversible Removed sections panel until forgotten/saved as documented
Copy/paste blocksSupported for compatible destinations, including allowed nested parents
Undo/redoButtons and keyboard shortcuts; up to 80 in-memory states with rapid-setting edits merged
Restore last sessionBest-effort local-browser snapshot, scoped to store/theme/template and offered only against the same saved base revision
Inline text editingSupported only when canvas text maps unambiguously to one text or inline_richtext setting
Preview failureExisting DOM is retained and the exact failed section/reason is surfaced
Default theme contentDedicated form editor for storefront locales/*.json; schema locale files remain code-edited

See Using the visual editor and Edit default theme content for the merchant workflow and recovery details.

Cart operations in preview call the normal buyer cart service and therefore must satisfy inventory, modifier, CSRF, and checkout rules. Preview is not a test-order emulator and does not bypass payments. For end-to-end order testing, use an isolated test store/payment configuration so the test does not alter a merchant’s production commerce state.

Cookie definitions and attributes are centralized so their purpose, lifetime, Secure, HttpOnly, SameSite, path, domain, and deletion behavior can be audited in one place. Cookies are divided by purpose:

PurposePolicy
Cart, checkout, authentication, CSRF, storefront password, previewStrictly necessary; set only for their documented workflow
Preferences/localizationUsed for the buyer-requested experience and kept separate from advertising
AnalyticsWritten or activated only after the applicable analytics consent
Marketing/pixel identifiersWritten or activated only after marketing consent

Global Privacy Control is treated as a marketing opt-out. Revoking consent stops future non-essential dispatch and clears Sellerlane-managed non-essential identifiers. A third-party pixel is not injected merely because it is configured; it must also pass consent, channel, event allowlist, CSP, and payload policy.

Every state-changing same-origin buyer route uses the centralized CSRF boundary: a signed readable CSRF cookie/token pair, x-csrf-token or _csrf echo, and Origin/Referer/fetch-metadata checks. Login/OTP, preview, analytics-context, visitor, cart, and pixel tokens have distinct purpose-specific claims and are not interchangeable.

Cloudflare location headers are accepted only from the trusted edge path, normalized, range-checked, and reduced to the fields the analytics model is allowed to retain. A buyer-supplied country, latitude, or longitude header is not trusted as edge geolocation.

S3, R2, and public asset policy

The storage bucket is not the public security boundary. Both S3 and R2 remain private with public-access prevention enabled; the application or edge Worker decides which object classes can be served.

Object classStorage/access policy
Published theme assets from assets/Public only through the allowlisted versioned storefront/CDN route; immutable live caching
Merchant media intentionally published to buyersPublic only through the media Worker/CDN route with normalized keys, content types, range handling, and the configured CORS policy
Public font libraryPublic through the font route; cross-origin font CORS only
Draft theme assetsPreview-authorized route; no-store; not generally public
Theme source, config, locales, templates, sections, snippetsPrivate; never exposed as raw bucket objects
_compiled/themes/v1/*Private application artifact; CloudFront/viewer access must be denied
Product-modifier uploads, digital files, exports, private documentsAuthenticated or short-lived signed access only
Sitemap snapshotsPrivate S3 application data; served by the buyer origin after domain rewrite

Do not attach an R2 development domain or a whole-bucket custom domain to the production bucket. The Worker allowlist, not the presence of an assets/ folder name alone, controls public delivery. Likewise, S3 Block Public Access stays enabled and the CDN must explicitly deny /_compiled/*.

Sitemap, domains, and SEO

The sitemap is generated as a bounded snapshot and stored privately in S3. It is not a public R2 object. On GET /sitemap.xml, the buyer service applies the current canonical public origin so one store can serve the correct URLs on its active custom domain without rebuilding the logical sitemap for every domain request.

SEO routes such as robots.txt, sitemap, canonical tags, and alternate-language links are served only for an accepted store origin. The storefront also:

  • emits one canonical URL for the active public domain and normalized path;
  • emits hreflang links only for published locales and their real localized equivalents;
  • avoids indexing preview, editor, checkout/session, and error state URLs;
  • preserves locale in product, collection, article, page, pagination, and filter links;
  • uses structured product/site data derived from canonical server data; and
  • prevents query-only filter/sort/pagination state from becoming competing canonical pages.

Current Shopify changelog coverage

The compatibility review includes these current public theme changes:

Shopify changeSellerlane status
Stricter Liquid syntax validationImplemented at save/import/publish and runtime
article_list settingImplemented
Standardized asset URL ?v= parametersImplemented
Automatic stylesheet subsettingImplemented for full pages and section fragments
Storefront agents.md, llms.txt, and llms-full.txt discoveryImplemented
color_palette settingImplemented
Standard storefront events and actionsImplemented
App-block maximum increaseNot applicable because apps/app blocks are intentionally unavailable

Upstream references: Shopify theme changelog, theme architecture limits, Liquid form tag, storefront filtering, pagination limits, stylesheet subsetting, and standard events/actions.

Deliberate differences and open work

Do not describe these as strict parity:

  • standard product attribute filters (filter.v.t.shopify.*) because the enabled taxonomy attribute identity and custom-value Metaobject GID mapping are not persisted yet;
  • metaobject system.url currently normalizes a fallback URL even when the definition lacks the online-store capability; the corresponding page route still refuses to render, so themes must link it only for web-enabled types;
  • Shopify apps, app blocks, app embeds, and app checkout extensions;
  • Shopify Markets country/catalog/currency switching;
  • Shopify’s B2B Liquid surface — company/company_location objects and Markets-based contextual pricing fields. Sellerlane B2B wholesale (companies, locations, negotiated catalogs, terms) exists as a typed extension whose Liquid contract is documented on the shop, customer, order, product, and variant object pages;
  • password-based customer account activation/recovery/reset forms;
  • selling plans/subscriptions;
  • arbitrary cart attributes[...] and line properties[...] persistence;
  • deprecated Shopify Liquid tags/filters;
  • full RFC 9421/Web Bot Auth crawler signatures (Sellerlane currently has a store-scoped token-hash v1 contract); and
  • Shopify-proprietary network, fraud, Shop, or payment signals.

Sellerlane’s typed modifiers, event bookings, digital delivery, gift cards, bundles, quote requests, stock alerts, OTP accounts, loyalty, B2B wholesale, and other namespaced features are Sellerlane extensions. They can exceed Shopify core in product breadth without making a Shopify-portability claim.

Store-wide password access, home-page SEO/social metadata, spam protection, crawler tokens, locale behavior, and pixel navigation are documented in Online store preferences.

Release and operations checklist

Before declaring a theme-runtime release ready:

  1. Run strict validation against the default theme and malformed fixtures.

  2. Run buyer typecheck, build, production dependency audit, and the full buyer test suite.

  3. Run seller targeted theme/filter/cart tests and the full Go suite.

  4. Build the marketing documentation and verify internal links.

  5. Typecheck and dry-run the R2 Worker for the production environment.

  6. Verify S3 Block Public Access, compiled-prefix application permissions, and CDN denial for /_compiled/*.

  7. Verify the R2 Worker/custom-domain migration and restricted CORS policy before removing a legacy public endpoint.

  8. Exercise publish, rollback, preview revocation, localized navigation, cart mutation, section replacement, consent changes, sitemap custom-domain rewrite, and filter/pagination reset in a staging store.

The code test gate proves application behavior. IAM, bucket public-access, CloudFront, R2 custom-domain, Worker deployment, and CORS changes must also be applied and verified in the live cloud account; repository policy files alone do not change deployed infrastructure.