What is a Component in Noir#
A Component is a platform-rendered building block included by ComponentsList.liquid.Components are arranged in page sections (Header / Body / Footer) and are rendered dynamically based on the component model:The renderer resolves a template include name using:Components_<model.Name>_<model.View>
So component template naming must remain consistent with what the platform sends.
Where components live#
Each component lives under:Most components follow this structure:Components/<Name>/Default.liquid
The Liquid template (markup + bindings).
Default.js (optional)
Client-side behavior for the component.
Components/<Name>/Default.json (optional)
Translation keys used by model.Translations.*.
Note
Even if a component doesn't currently need JavaScript or translations, we still keep the standard file set for consistency:Default.liquid (required)
Default.js (kept even if empty/minimal)
Default.json (kept even if empty/minimal)
This makes components easier to maintain, extend, and document, and keeps the theme structure uniform across all component folders.
Model conventions (common fields)#
Component templates receive a model object.Settings#
model.Settings.Id
Used for a deterministic DOM id. Example pattern:
{% assign id = model.Settings.Id %}
<section id="comp-{{ id }}">
...
</section>
model.Settings.CssClass (optional)
Additional CSS classes for the outer wrapper. Common pattern is to apply only when non-empty and not (UNDEFINED).
Translations#
If a component has a Default.json, keys are available as:Use translations for UI labels or messages that must be localized.
JS conventions#
Where JS is loaded from#
/Themes/Noir/componentscripts.js (component/reusable scripts compiled/aggregated)
theme.js (theme-wide utilities + Alpine stores)
This implies the component's JS must work with the global execution model and the script loading order.Alpine-friendly globals#
Many components use Alpine directives (x-data, [x-show], x-transition]) and rely on:global objects exposed by each component script, and/or
Alpine stores defined in theme.js.
Rule: cross-component state belongs in Alpine stores (theme-wide).
Styling conventions#
Noir uses Tailwind as the primary styling approach:prefer Tailwind utility classes in Liquid templates
use CSS variables for theme tokens when available
use Custom CSS only for small overrides
avoid adding new bespoke CSS unless necessary
Safe editing rules#
Do not rename component folders lightly (model.Name must match the folder/template naming convention).
Keep the Default view naming consistent unless there is an explicit need for a new view.
If you introduce new JS behavior, ensure it doesn't conflict with existing global utilities or Alpine stores.
If you add new translation keys, ensure the template uses model.Translations.* consistently.
Modified at 2026-04-14 13:18:56