What is Noir#
Noir is a Shopranos storefront theme implemented with Liquid templates and a section-based page composition model.
Pages are rendered by the main layout template (Structure/LayoutA.liquid) and are composed from Header / Body / Footer component lists.Key technologies used in Noir:Liquid for server-side rendering and template composition
Tailwind CSS for styling (generated bundle: output.css)
Alpine.js for interactive UI behavior and shared state (stores)
Vendor libraries loaded by the layout (e.g. axios, swiper, leaflet, lightgallery, nouislider)
This documentation describes how Noir is structured, how it renders, and how to extend it safely.
Theme structure#
This documentation focuses on the following theme folders:Structure/
Layout and infrastructure templates (layout, metas, CSS variables, component list renderer, debug utilities).
Components/
Platform-rendered components. Each component typically includes:Default.liquid (markup + bindings)
Default.js (client behavior, if needed)
Default.json (translations/strings, if needed)
Reusables/
Theme-only building blocks that can be rendered from other templates (often used for modals, buttons, shared UI pieces).
Reusables follow the same file pattern (Default.liquid, optional Default.js, optional Default.json).
Assets/
Static assets: CSS, JS, fonts, images, vendor libraries.
How rendering works (high level)#
Main layout template: Structure/LayoutA.liquid
It outputs the page shell (<head>, CSS/JS includes, header/main/footer) and renders the component lists.
Component list renderer: Structure/ComponentsList.liquid
It iterates components and includes the correct template by naming convention.
At runtime, the layout injects some globals into window (feature flags and basic user info), which are used by JavaScript and Alpine stores.Assets are referenced via GlobalData.RootPath and versioned with GlobalData.Settings.Version.
Component include convention#
The component list renderer resolves each component template name using:Components_<model.Name>_<model.View>
model.Name = "Announcement"
will be rendered via the include:Components_Announcement_Default
This convention is critical: if the Name / View combination doesn't match an existing template, the component won't render.
Common data you'll see in templates#
Component model#
Component templates receive a model object. Common fields:model.Settings.Id
A deterministic identifier used for DOM ids.
model.Settings.CssClass
Optional CSS class (used to customize spacing/appearance).
model.Translations.*
Strings backed by the component's Default.json (when available).
Global objects (Liquid)#
Across templates you will commonly see:Root
Page and user-related data.
GlobalData
Global settings and paths (e.g. root path, version for cache busting).
Client-side architecture#
Theme-wide JS: Assets/js/theme.js
Contains shared utilities and cross-component logic (e.g. cookies, observers, GA helpers) and is the home for Alpine stores.
Theme "SDK / Services": Reusables/Services/Default.js
Exposes a servicesreusabledefault object with helper methods and API calls used by components/reusables (e.g. wishlist, shopping lists, product search helpers).
Component / Reusable scripts
Many components/reusables register Alpine-compatible objects or factories and rely on the layout's script loading order.
Styling approach#
Main CSS bundle: output.css (generated from Tailwind)
Custom styles: stored under Assets/scss/ and compiled into CSS that is imported by the Tailwind entrypoint.
When adjusting markup, prefer existing Tailwind utility classes. Avoid introducing new custom CSS unless needed.
Debugging tips#
Use the theme's JSON/debug helpers (see Structure/Json.liquid) to inspect view models in the browser.
Inspect runtime globals injected by the layout (feature flags, user auth state) via DevTools.
How to use this documentation#
Start with Structure to understand the rendering pipeline, layout responsibilities, and runtime globals.
Use Components and Reusables for implementation details and patterns.
Use Assets for pipeline/vendor/library guidance.
Use SDK for the theme-side service methods and API call breakdown.
If you're extending Noir, always follow the existing naming conventions and shared-store patterns to avoid breaking cross-component behavior.Modified at 2026-04-14 13:18:56