1. The mental model
There are three separate responsibilities. Keeping them separate is the key to understanding v1.
Eyivo Core
Stores company details, pages, media, SEO, navigation and publishing state. It is the source of truth for content.
Theme package
Defines fixed page shapes, allowed sections, custom component schemas and CSS. It never queries data or executes application code.
App editor
Generates safe forms from the schema. Owners may update text, images, pages and section order inside an area.
Not a page builder: an owner can add a permitted section to main and choose its numeric position. They cannot create a new area, drag a hero into the footer, alter HTML, or modify your CSS.
2. Quick start: a minimal, usable template
Every v1 theme owns its complete layout, styles and scripts, and may arrange them in any design its author chooses. Themes never inherit a layout or asset from another theme. Common eyivo: components and the seven fallback page types come from theme-core; a theme only stores the page types it overrides and components it declares in the theme: namespace.
Every v1 theme needs a default layout file. Both page-types/ and components/ are optional when the package uses only core fallbacks:
acme-industrial/
├── theme.json
├── layouts/default.liquid
├── page-types/
│ └── home.liquid # optional override
├── components/
│ └── featured_course.liquid
├── locales/
│ ├── en.json
│ └── tr.json
└── assets/
├── css/theme.css
└── js/theme.js
layouts/default.liquid always comes from the active theme and owns the complete public document. Eyivo first looks for the requested page type in that theme, then falls back to theme-core/page-types. Core never supplies a layout or assets, so the fallback page content is still wrapped and styled by the active theme.
3. Describe the template in theme.json
The manifest is both a capability declaration and the contract used to generate App forms. It answers three questions: which page structures exist, which areas each structure has, and what a component is allowed to store. Built-in themes explicitly declare all ten standard page types and include their corresponding Liquid files. Custom themes can continue to use core fallbacks for undeclared page types.
{
"name": "Acme Industrial",
"version": "1.0.0",
"eyivo_theme_api": "1.0",
"settings": {
"primary_color": { "type": "color" },
"button_radius": { "type": "number" }
},
"page_types": {
"home": {
"areas": {
"hero": {
"allowed_components": ["eyivo:hero"],
"min": 0,
"max": 1
},
"main": {
"allowed_components": ["eyivo:rich_text", "eyivo:image_text", "theme:featured_course"]
}
}
},
"page": { "areas": { "main": { "allowed_components": ["eyivo:rich_text"] } } }
},
"components": {
"featured_course": {
"variants": ["card", "compact"],
"schema": {
"heading": { "type": "text", "required": true, "translatable": true },
"summary": { "type": "textarea", "translatable": true }
}
}
}
}
| Key | Meaning | Example |
|---|---|---|
version | Your immutable theme release version (semantic versioning). | 1.2.0 |
eyivo_theme_api | The Eyivo public API contract your package supports. | 1.0 |
areas | Named slots that your Liquid page file renders in fixed places. | hero, main, bottom |
allowed_components | Which components the editor may add to one area. | ["eyivo:hero"] |
components | The active theme’s custom theme: component definitions. Shared eyivo: definitions stay in theme-core. | featured_course |
min/max | Optional limits on the number of sections in that area. | max: 1 |
Page-type fallback: the built-in types are home, page, gallery, contact, products, product and videos. Omit any of them to use its definition and Liquid file from theme-core. Declare a type only when the theme also supplies its matching page-types/<type>.liquid override.
The editor receives the merged page-type API: active-theme definitions replace matching core definitions, while every omitted type remains available from core.
4. Complete demo content in demo.json
Every upload must include a portable, draft-only demo.json fixture and at least one screenshot captured with that fixture loaded. Built-in themes use the same schema. Do not include database IDs, tenant domains, credentials, or object-storage credentials.
{
"schema_version": 2,
"default_locale": "en",
"label": "Northline Build Co.",
"summary": "Thoughtful construction for the way life happens.",
"media": {
"media/hero.jpg": {
"public_url": "https://cdn.example.com/demo/hero.jpg",
"mime_type": "image/jpeg",
"original_name": "hero.jpg",
"bytes": 184000,
"width": 1600,
"height": 900
}
},
"company": { "display_name": "Northline Build Co.", "logo_asset": "media/hero.jpg" },
"theme_settings": { "settings": { "header_cta_url": "/contact" } },
"pages": [],
"catalog": [],
"galleries": [],
"videos": []
}
| Key | Purpose |
|---|---|
media | Public source URLs and metadata keyed by portable asset identifiers. Reuse the identifier for hero_asset, cover_asset, media_asset, gallery-item asset, logo_asset, and favicon_asset. |
company | Company profile, social links, brand colors, optional logo/favicon asset, and locale-keyed translations. |
theme_settings | Initial theme settings, with optional locale-keyed translations. |
pages | Type, sort order, navigation state, SEO, page settings, components, and locale-keyed content. |
catalog | Catalog entries with locale-keyed content and an optional cover_asset. |
galleries | Gallery metadata and image items. Every gallery item needs an asset and non-empty alt_text. |
videos | An external source_url or a media_asset, presentation mode, and locale-keyed content. |
Pages and components
{
"type": "home",
"sort_order": 0,
"navigation_visible": true,
"hero_asset": "media/hero.jpg",
"translations": {
"en": { "slug": "home", "title": "Home", "meta_title": "Home | Northline" },
"tr": { "slug": "ana-sayfa", "title": "Ana sayfa", "meta_title": "Ana sayfa | Northline" }
},
"components": [{
"component_type": "eyivo:hero",
"area": "hero",
"position": 100,
"variant": "split",
"data": { "primary_url": "/contact" },
"translations": {
"en": { "heading": "Built for real life", "primary_label": "Contact us" },
"tr": { "heading": "Gerçek yaşam için tasarlandı", "primary_label": "Bize ulaşın" }
}
}]
}
Component types and areas must be declared in the active theme manifest or theme-core. Use relative paths such as /contact for same-site links. Bundled homepage demos use their existing hero image as a full-width background with a readable overlay and responsive text: immersive in most themes, and image-backed centered in Compact. Other hero variants retain their own layouts.
Demo languages and fallback
English is the required base language: set default_locale to en. Omitted values in older fixtures also mean English. Every other supported site language is optional; do not copy English text into another locale and present it as a translation.
Provide translations.en and optional locale objects for company copy, theme settings, pages, components, products, galleries, gallery-item captions and alt text, videos, and blog posts. Legacy unkeyed English fields remain supported. Creation selects the site’s native language and falls back to English for each missing field. Arrays replace the entire English array; explicit empty values are preserved. Only the selected site language is imported, without automatically enabling English or other locales.
Use English source slugs in same-site links and portable menu entries. Import maps them to the selected translation’s slug, including links in rich text and blog documents. Menu entries may supply explicit slugs and labels maps. Missing label overrides fall back to English. External URLs are unchanged.
{
"company": {
"translations": {
"en": { "display_name": "Northline", "description": "Built around your needs." },
"tr": { "display_name": "Northline", "description": "İhtiyaçlarınıza göre tasarlandı." }
}
},
"theme_settings": {
"settings": { "header_cta_url": "/contact" },
"translations": {
"en": { "header_cta_label": "Contact us" },
"tr": { "header_cta_label": "Bize ulaşın" }
}
},
"menus": {
"footer": [{ "type": "page", "slug": "contact",
"slugs": { "en": "contact", "tr": "iletisim" },
"labels": { "en": "Contact us", "tr": "Bize ulaşın" }
}]
}
}
Import and media safety
New dashboard sites include demo data by default and immediately publish the selected language; owners can uncheck this option. Loading a demo from Branding on an existing site still creates drafts and preserves published content. The central App copies images into the new site’s media library and sends references through the Internal API. Masters and themes never receive object-storage credentials. Themes render the supplied media.public_url.
Declare screenshots in theme.json.preview with data_source: "demo_data". The package must contain every declared preview image.
5. Write any layout your theme needs
The default layout owns the complete HTML document. Nothing outside the active theme supplies its header, footer, stylesheet, JavaScript or visual structure.
<!doctype html>
<html lang="{{ locale.code }}" dir="{{ locale.direction }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% eyivo_head %}
<link rel="stylesheet" href="{{ 'css/theme.css' | asset_url }}">
</head>
<body>
<header class="site-header">
<a href="{{ locale.home_url }}">{{ company.name }}</a>
<nav>
{% for item in navigation.main %}
<a href="{{ item.url }}">{{ item.label }}</a>
{% endfor %}
</nav>
</header>
{{ content | raw }}
</body>
</html>
A page-type file then decides exactly where its dynamic areas appear. Area components are already rendered HTML strings, so insert them with | raw. Ordinary values are escaped by default.
<main class="home-layout">
<section class="home-layout__hero">{{ areas.hero | raw }}</section>
<div class="home-layout__content">{{ areas.main | raw }}</div>
<aside class="home-layout__footer-cta">{{ areas.bottom | raw }}</aside>
</main>
Render a component directly
A designer may place a registered component directly in a layout or page-type file. This placement is fixed by the theme and is not reordered or removed in the panel. Pass an object through data:, individual schema fields, or both; named fields override matching keys from data:.
{% eyivo_component "eyivo:cta",
eyebrow: "Let’s talk",
heading: page.title,
text: company.description,
button_label: "Contact us",
button_url: routes.contact
%}
{% eyivo_component "theme:featured_course",
data: page.settings.featured_course,
variant: "compact"
%}
The type must be a quoted namespaced literal. Direct rendering uses the same schema, variants, component file and normalized component object as an area instance. Component files cannot render other components.
Assets: always use {{ 'css/theme.css' | asset_url }}. Eyivo serves it from the active package as /theme-assets/<theme>/css/theme.css; do not hard-code another theme name or filesystem path.
Head, routes and interface dictionaries
Every layout must render {% eyivo_head %} exactly once. Eyivo then owns the title, description, robots, canonical, hreflang, Open Graph and structured-data output. Use routes.home, routes.contact, routes.catalog, routes.gallery and routes.videos instead of hardcoded public paths. Pass editable URL settings through | localized_url so known internal paths gain the active locale prefix while external URLs remain unchanged.
{{ 'Menu' | t }}
{{ theme.settings.header_cta_url | localized_url }}
Create optional locales/<locale>.json files for interface labels introduced by the theme. Lookup order is core English, core locale, theme English, then theme locale. Shared labels from theme-core therefore work without copying files. Business copy belongs in translatable content, component fields, or theme-setting fields—not dictionaries.
A custom component file
<article class="featured-course featured-course--{{ component.variant }}">
<div class="featured-course__content">
<h1>{{ component.data.heading }}</h1>
{% if component.data.summary %}<p>{{ component.data.summary }}</p>{% endif %}
</div>
</article>
For translatable fields, Eyivo selects the visitor’s locale before rendering. A Turkish visitor and an English visitor therefore see the same component structure with different component.data.heading values.
6. The safe Liquid data you can use
Liquid receives plain, normalized data—not Laravel or database models. If a value is not in this table, treat it as unavailable in v1.
| Object | Useful fields | Typical use |
|---|---|---|
site | name, locale | Site-level label and native locale. |
company | name, legal_name, description, address, phone, email | Header, footer and contact information. |
page | id, type, title, slug, body, settings | Generic page content and per-page settings. |
seo | title, description, canonical/robots/Open Graph values when supplied | Document head. |
navigation.main | Each item has label, url, active | Site menu. |
locale | code, name, native_name, direction, is_default, home_url, available | Document language, RTL direction, localized home links and language selectors. |
routes | home, contact, catalog, gallery, videos, blog | Locale-correct system URLs; never build prefixes in Liquid. |
blog | title, url, categories, category, posts, post, pagination | Free blog listing, category archive, and article pages. Posts expose title, summary, URL, dates, categories, and cover media. Only blog.post.body_html contains server-generated safe article HTML and should use raw. Pagination supplies previous_url and next_url. |
theme.settings | Your manifest settings | Use a configured color, spacing or design option. |
products/product | Translated title, URL, summary and body | Product listing/detail page types. |
galleries | Translated title and description | Gallery page type. |
videos | title, description, source_type, source_url, playback_url, media | Use playback_url for uploaded video files and source_url for external HTTP(S) videos, according to source_type. Attached images are never video sources. Do not use the video file itself as a poster image. |
component | id, type, variant, data | Inside a component file only. |
Locale-safe layout example
<html lang="{{ locale.code }}" dir="{{ locale.direction }}">
<a href="{{ locale.home_url }}">{{ company.name }}</a>
{% if locale.available.size > 1 %}
<nav aria-label="Language">
{% for language in locale.available %}
<a href="{{ language.url }}" lang="{{ language.code }}"
{% if language.current %}aria-current="page"{% endif %}>
{{ language.native_name }}
</a>
{% endfor %}
</nav>
{% endif %}
Each available-language item also exposes label, direction, is_default, current, and has_translation. Eyivo supplies only equivalent published translations, so themes must use language.url instead of constructing /en or any other prefix.
Example of a settings-driven token: style="--brand: {{ theme.settings.primary_color }}". The setting must first be declared in theme.json.
7. Components: direct and dynamic
Components have one rendering contract with two placement choices. A direct component is controlled by the designer in a layout or page type. A dynamic component is stored as a page-area instance and controlled through the editor. Dynamic instances have a stable ID, namespaced type, area, position, optional variant, data and translations. Position is only ordering—not identity.
Field types
text, textarea, richtext, number, boolean, select, url, email, image, video, file, color, icon, page, product and repeater.
Namespaces
eyivo: resolves from theme-core/components, theme: resolves from the active theme, and plugin: is reserved for future plugins. Use the exact namespaced type in an area or eyivo_component tag.
Universal component: set "universal": true on a component definition to allow it in all areas of compatible page types. It still must have a valid schema and Liquid file.
Shared action links localize known internal paths while preserving query strings and fragments. Rich text retains safe formatting inside nested editor containers. Empty gallery images are omitted, map images without a destination are not links, and slider and search labels use the visitor's interface language.
Visual Atelier (visual-01) keeps its decorative homepage ticker flowing automatically, including when the browser requests reduced motion. Hovering pauses the text; leaving resumes it. The original appearance and CSS-only loop are preserved.
8. Available component catalog
These 30 shared eyivo: components form the complete v1 library and resolve from theme-core. A theme may additionally declare and implement its own theme: components.
Variants: spliteditorialcenteredimmersive
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
Yes | Yes | — |
summary |
textarea |
No | Yes | — |
image_url |
url |
No | No | — |
image_alt |
text |
No | Yes | — |
primary_label |
text |
No | Yes | — |
primary_url |
url |
No | No | — |
secondary_label |
text |
No | Yes | — |
secondary_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
body |
richtext |
No | Yes | — |
Variants: image_leftimage_rightoverlap
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
body |
richtext |
No | Yes | — |
image_url |
url |
No | No | — |
image_alt |
text |
No | Yes | — |
badge |
text |
No | Yes | — |
button_label |
text |
No | Yes | — |
button_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
intro |
textarea |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
intro |
textarea |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
intro |
textarea |
No | Yes | — |
button_label |
text |
No | Yes | — |
button_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
text |
textarea |
No | Yes | — |
submit_label |
text |
No | Yes | — |
form_binding |
select |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
heading |
text |
No | Yes | — |
text |
textarea |
No | Yes | — |
whatsapp_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
address |
textarea |
No | Yes | — |
map_url |
url |
No | No | — |
image_url |
url |
No | No | — |
image_alt |
text |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
heading |
text |
No | Yes | — |
placeholder |
text |
No | Yes | — |
categories |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
summary |
textarea |
No | Yes | — |
video_url |
url |
No | No | — |
poster_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
price |
text |
No | Yes | — |
period |
text |
No | Yes | — |
features |
repeater |
No | Yes | — |
button_label |
text |
No | Yes | — |
button_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
label |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
body |
textarea |
No | Yes | — |
button_label |
text |
No | Yes | — |
button_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
The shared eyivo:faq component keeps the same fields and markup in every theme. Each theme presents it in that theme’s own type, spacing, and color.
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
text |
textarea |
No | Yes | — |
button_label |
text |
No | Yes | — |
button_url |
url |
No | No | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
heading |
text |
No | Yes | — |
items |
repeater |
No | Yes | — |
Variants: none
| Field | Type | Required | Translatable | Options |
|---|---|---|---|---|
eyebrow |
text |
No | Yes | — |
heading |
text |
No | Yes | — |
intro |
textarea |
No | Yes | — |
items |
repeater |
No | Yes | — |
Foundation Impact: composing a foundation website
Foundation Impact (foundation-impact) presents a foundation’s purpose, programmes, governance, impact, events, gallery and enquiries. Its layout wraps long navigation labels and switches to an expandable menu on smaller screens. Registered header, footer and useful_links menus control navigation. The header falls back to automatic page navigation when its registered menu is empty. The curated photo page uses /in-pictures; /gallery remains the native album listing.
Foundation Impact owns all ten built-in page templates: Home, Page, Contact, Products, Product, Gallery, Videos, Blog, Blog Category and Blog Post. Existing content areas and registered forms remain compatible. Parent navigation uses the same transparent, underlined hover and current-page styling as ordinary links; a selected child also marks its parent. Submenu links follow the same treatment on desktop and mobile.
Subpage heroes without an image use a compact lavender banner with closely spaced breadcrumbs, a small eyebrow and a restrained title. Image-backed subpage heroes add a dark overlay and white titles, breadcrumbs and summaries, with the text above the image and overlay layers. The overlay direction follows right-to-left layouts.
The shared eyivo:rich_text component accepts both editor-marked bodies and legacy HTML bodies. Both pass through the existing formatting allow-list, so paragraphs, headings, lists and safe links display as content while scripts, event handlers and unsafe links are removed. Other text fields keep their normal escaping. Foundation demo rich-text bodies use the editor marker as well.
The theme composes existing eyivo:hero, project_grid, image_text, event_list, media_gallery, feature_grid, team_grid, stats, rich_text, faq, cta and lead_form components. Its deferred theme script enables image-slider controls, keyboard-accessible tabs and catalog filtering. The mobile menu expands using native HTML controls. Stats use dark headings, labels and notes on a pale yellow surface, with blue values. Programme cards link to normal content pages. Event cards describe events and link to an enquiry route; they do not create bookings or attendance records.
Its contact page uses eyivo:lead_form with the portable contact binding supplied by eyivo/contact. Importing a demo resolves this binding separately for each site. Donations, grant applications and volunteer approvals are not included.
Built-in demo imports reuse active entries in the shared theme-demo media catalog. The central app owns the object and supplies references to masters; deleting an imported reference does not delete the protected shared object. A theme preview and a dedicated SEO example are separate sites.
Village Commons: secondary navigation and sidebars
Village Commons (village-commons) combines a noticeboard, local places, village history, events, photographs, visitor information and a site-specific contact form. Forest green, ivory and amber surfaces have explicit foreground colors. Existing Eyivo components provide the content; event cards do not provide bookings, and meeting-note pages do not constitute an official records system. Image-and-text sections on information pages keep responsive inner padding around the copy. Subpage event and FAQ panels have responsive inner padding. FAQs use a compact heading and stacked, rounded disclosures with clear expand controls.
Register header, secondary, sidebar, footer and useful_links in theme.json. Secondary navigation appears in the utility bar; the sidebar menu appears beside ordinary and contact pages. Both are edited and published through the standard menu editor. Keep primary navigation short. On small screens the primary menu expands and the sidebar moves below the page content.
A sidebar is a layout region, not a new component type. The page and contact schemas declare a sidebar area for rich_text, announcement, download_list and contact_actions, with a maximum of three instances. Render areas.sidebar inside an aside, alongside navigation.sidebar. Village life demonstrates an editable text widget. Theme settings supply the additional contact card. Each custom area must be declared separately on every page type that uses it.
{% if navigation.secondary.size > 0 %}
<nav aria-label="{{ 'Useful information' | t }}">
{% for item in navigation.secondary %}
<a href="{{ item.url }}"{% if item.active %} aria-current="page"{% endif %}>{{ item.label }}</a>
{% endfor %}
</nav>
{% endif %}
<aside aria-label="{{ 'More information' | t }}">
{% for item in navigation.sidebar %}
<a href="{{ item.url }}">{{ item.label }}</a>
{% endfor %}
{{ areas.sidebar | raw }}
</aside>
The general theme preview and WT-003 English dedicated demo are separate admin-1 sites. Images are imported by the central app and protected in the shared demo-media catalog. Screenshots of the separately published test fixtures are captured locally before deployment and packaged with the theme and Apex. Prepare verifies the blueprint hash and theme version before binding the capture revision to the generated demo. The public catalog discovers its protected preview through the authenticated App API. Screenshots are separate from customer media. The theme uses the portable contact form binding from eyivo/contact.
Forms and submission history
Forms API 1 provides seven approved processors. Themes own layout and styling; plugins own schemas, validation and workflow. The host handles persistence, verification and notifications.
| System plugin | Form type |
|---|---|
eyivo/contact | Contact contact |
eyivo/quote-request | Quote request quote_request |
eyivo/product-inquiry | Product inquiry product_inquiry |
eyivo/appointment-request | Appointment request appointment |
eyivo/course-application | Course application course_application |
eyivo/reservation-request | Reservation request reservation |
eyivo/property-inquiry | Property inquiry property_inquiry |
One form, reusable placements
Setup creates a retained default UUID per site/plugin/type. Reusing a placement keeps that identity; creating a named form gives a separate UUID. Theme changes and plugin reinstall preserve history. Themes declare portable aliases; the editor selects saved forms without asking customers to type UUIDs.
{
"plugins": ["eyivo/contact", "eyivo/quote-request"],
"forms": {
"contact": {"plugin":"eyivo/contact","type":"contact","schema_version":1,"instance":"default"},
"quote": {"plugin":"eyivo/quote-request","type":"quote_request","schema_version":1,"instance":"default"}
}
}
Use forms.contact in contact templates and component.form in lead sections. Replace form_preset with form_binding. Render supplied fields and guidance, action, CSRF, signed form_context and verification_html. Only declared presentation overrides and permitted additional fields are accepted; required validation cannot be weakened.
forms.contact · component.form · form_binding · form.fields · form.action · form.csrf_token · form.context · form.verification_html
Two inbox views, one record
The shared site inbox and each form plugin’s own list/detail pages show the same records. Form packages require Panel API 2 submission-list/submission-detail components and a flat menu link. Panel API 1 remains supported. Viewing does not mark records read; read/archive/workflow states are separate and edits use record_revision. Disabled plugins lose menus/pages, while the shared inbox retains historical snapshots.
{"components":[{"type":"submission-list","form_type":"contact","detail_page":"submission"}]}
{"components":[{"type":"submission-detail","form_type":"contact","list_page":"submissions"}]}
Customer data and permissions
Form records stay in the assigned site content database and share the existing package max_db_bytes allowance with other content. No separate submission-count or retention quota is added. Configuration remains in the master database with limits of 50 fields, 32 KB and three levels. Members can view; owner/manage permissions govern changes. Plugins receive no direct database access, and PHP/Blade never moves to the app.
Verified saving and notification
The host validates signed context, declared answers and required Human Verification, then commits the record, usage and notification work together. Identical attempts and payloads recover for 24 hours without saving twice. SMTP delivery runs afterward and may retry; an email failure does not undo a saved record. An unset form recipient falls back to the company email; if neither address is valid, the submission is saved without email.
All shipped themes use this contract. Legacy contact POSTs return 410; contact-page GET links still work. Appointment and reservation requests do not confirm bookings. Third-party form processors, file uploads and arbitrary external actions are not included.
POST /__eyivo/forms/{UUID}/submissionsGET /__eyivo/forms/{UUID}/challenge
Field Guide: readable guides and resource libraries
Field Guide (field-guide) pairs an editorial serif with readable body text, navy backgrounds, green actions and restrained gold accents. The hero and optional orientation area share a responsive introduction. Background photography stays subdued behind the copy; an empty orientation area lets the introduction use the full width.
The desktop masthead shows the first four top-level page links and puts the remaining links under More. Parent pages retain their own links and separate submenu toggles. On smaller screens a native expandable Menu exposes every page and child link. Escape and clicking outside dismiss the navigation disclosures. Language links appear only when more than one language is available.
Use the hero and orientation areas for the introduction and quick orientation, and the main area for existing Eyivo components. A feature grid following editorial content becomes a supporting checklist on wide screens and follows it on mobile. Rich-text articles have a readable line length, clear heading spacing and contained photographs with visible credits. When an article ends in a single subheading followed by a checklist or short note, the theme script presents that existing content as a supporting sidebar on desktop and below the article on mobile; it remains readable without JavaScript. A closing homepage rich-text section whose formatted body is one paragraph containing HTTPS links becomes a full-width navy reference band with a smaller gold heading and light green links, including without JavaScript. Linked guide collections use an editorial index with optional image_url and alt fields on each service_grid item, full-entry links and keyboard focus. The homepage leads with two illustrated guides, then gives the following collection a featured guide beside compact resource rows. Informative or mixed service lists use numbered reading panels; only items with an authored URL have an action. Thumbnails use supplied media URLs and never fetch destination pages. Contact forms and the footer use the same spacing and colors. The fictional Northwater Brief catalog demo remains separate from the BACC-GA migration fixture; refreshing the catalog demo does not import a customer website.
Automotive Care: workshop pages and media
Automotive Care (automotive-care) owns Home, Page, Contact, Products, Product, Gallery and Videos templates, alongside its blog templates. Existing component areas remain compatible. Its dark and gold design uses restrained headings, numbered service cards, separate credential labels and notes, and calls to action with space between text and buttons. Subpage hero images sit behind a contrasting overlay; pages without an image use a plain introduction.
Desktop navigation shows six top-level links and puts the rest under More. Parent links and their separate child-menu toggles share the same hover and current-page treatment. The expandable mobile Menu includes every page and child link. Escape and clicking outside close the menu. Language links appear only when several languages are available.
Catalog images retain their proportions within bounded frames, including large uploaded photographs. The shared base templates also constrain product images and position subpage hero backgrounds correctly. The gallery leads with a featured photograph; clicking an image opens an accessible dialog, Escape closes it and focus returns to the image link. Without JavaScript, the original image opens in a new tab. Image sliders support touch, arrow buttons, keyboard navigation and reduced motion; catalog search filters entries locally. Product detail photographs fill the full frame width with a centered cover crop. Credentials form a dark band with gold shield icons, while feature items use spacious columns with gold badges and stack on small screens.
Wellness & Beauty: personal care and treatment collections
Wellness & Beauty (wellness-beauty) owns Home, Page, Contact, Products, Product, Gallery and Videos templates alongside its blog templates. Existing component areas and form bindings remain compatible. Blush backgrounds, rose accents, restrained serif headings and arched photographs give the theme a softer studio identity. Text and actions have explicit spacing. Treatment detail pages use a spacious introduction, a centered cropped cover photograph and a readable body. Catalog cards have contained images and clearly separated descriptions and actions; gallery photographs sit in soft album frames with captions.
Ordinary navigation links and parent links share the same rose hover and current-page treatment. Parent pages keep separate submenu toggles; desktop overflow links appear under More, and the native mobile Menu includes all pages and children. Escape and clicking outside dismiss menus. The gallery opens full-size photographs in a dialog and restores focus on closing; without JavaScript the image opens in a new tab. Catalog search filters locally. Sliders and tabs support keyboard controls and reduced motion. Existing brand colors are respected; the theme adds no booking backend.
Veterinary Care: services, people and clear contact details
Veterinary Care (veterinary-care) owns Home, Page, Contact, Products, Product, Gallery and Videos templates alongside its blog templates. Existing component areas and registered forms remain compatible. Mint panels, dark green text, apricot actions and restrained rounded headings create a friendly practice identity. Team cards separate photographs, names, roles and biographies. Contact methods and address details place each label above its value, with readable phone and email links. The footer shows the company name, a modest tagline, description and contact details.
Regular links and parent links share mint hover and current-page states. Parents keep separate submenu toggles; additional desktop links appear under More, while the native mobile Menu includes every page and child. Escape and clicking outside close menus. Catalog cards have clear actions and local search; detail photographs fill bounded frames with a centered cover crop. The gallery features one large image with supporting views, and opens original photos in a dialog with focus restored on closing. Without JavaScript, image links open in a new tab. Sliders and tabs support keyboard controls and reduced motion.
Early Learning: playful pages for schools
Early Learning (early-learning) owns Home, Page, Contact, Products, Product, Gallery and Videos templates alongside its blog templates. Existing component areas and registered forms stay compatible. Cream backgrounds, coral, mint and yellow accents, rounded headings and building-block details suit early-years settings. Team profiles and the three About cards separate images, roles and descriptions. Contact information uses labeled panels, program details have a spacious introduction and centered cover photos, and gallery images sit in captioned album frames.
Navigation links and parents share outlined hover states and yellow current-page pills. Parents retain separate submenu toggles; More holds desktop overflow links and the native mobile Menu contains all pages and children. Gallery photos open in a dialog with focus restored on closing, or in a new tab without JavaScript. Local catalog search, keyboard tabs and sliders respect reduced motion. The demo uses school-specific team and program copy; it adds no enrollment backend.
Themes from the design collection
Each theme owns all ten standard page templates and styles all thirty shared Eyivo components. The included component and request example pages show sections beyond the homepage. Contact, quote, product enquiry, appointment, course application, reservation and property enquiry bindings use the existing plugins and Human Verification. Catalog filtering, keyboard tabs, image sliders and native navigation disclosures support the same content contracts across desktop, mobile and right-to-left layouts.
Seafood Restaurant
Seafood Restaurant (seafood-restaurant) pairs ocean navy with citrus orange, cool white pages and restrained Manrope headings. A photographic seafood hero leads into a compact benefits strip, signature dishes, a waterfront story, circular dish galleries and a navy reasons-to-visit panel. The fictional Tide & Table fixture includes reservation requests, ten page types, all thirty shared sections and all seven existing form bindings. Navigation links, parent links and More share hover and current-page states; selected children highlight their parent. Mobile menus keep child links beneath their parent. Tabs, sliders, dish filtering and right-to-left layouts retain the platform contracts. Reservation requests require confirmation; no payment or live table-availability system is implied.
Family Insurance
Family Insurance (family-insurance) pairs a violet masthead and inset white navigation with family photography, soft lavender information panels and restrained Manrope headings. Its Hearthway Insurance fixture is fictional. Plain and parent navigation links share the same hover and current-page treatment; a selected child highlights its parent. Compact subpage headings, captioned galleries, cropped catalog images and labeled contact panels extend the design beyond the homepage.
Barbershop
Barbershop (barbershop) follows a deep-green two-row masthead with a centered serif wordmark, a full-bleed photographic hero shaded from the reading side, and cream pages with Playfair Display headings and brass buttons. Feature cards draw line icons and show each icon value as a short gold label, credentials sit in a split dark band, the image slider shows four square cuts, product specifications become a two-column price list and price offers become a dashed rosette panel. Catalog cards on the homepage and services page are dark photographic tiles. Its Northline Barber fixture is fictional.
Recruitment & Staffing
Recruitment & Staffing (recruitment-staffing) uses white rounded navigation, a lavender split hero with an arched photograph, purple actions, mint testimonials and a blue-purple footer. Its fictional Brightlane Talent fixture includes recruitment-specific services, team profiles and enquiry copy. Plus Jakarta Sans headings remain modest. Parent and child navigation, catalog details, galleries, articles and all registered request forms follow the same visual language.
Airline Booking
Airline Booking (airline-booking) uses a white header with a plane mark, a rounded full-width sunset hero whose copy and actions sit in a floating white booking bar, and Figtree headings in teal and ink. Catalog cards become destination tiles with a numbered badge, image and text sits inside a mint panel with a teal caption chip, stats become a rounded teal band, feature cards become a two-column list with chevrons and the footer is a rounded teal panel with a contact action. Its Skyvane Travel fixture is fictional.
Architecture Studio
Architecture Studio (architecture-studio) places a transparent header with a frosted pill navigation over a full-bleed residence photograph washed with sand from the reading side, and uses light Montserrat headings, espresso pill buttons with white arrow discs and a floating project caption. Catalog and service cards are soft sand tiles with an asymmetric image corner, the project grid becomes a dark featured-projects band, image and text runs edge to edge with a rounded image edge, stats sit in a ruled column and lead forms become an espresso contact band. Its Solace Architecture fixture is fictional.
Automation SaaS
Automation SaaS (automation-saas) pairs a white header and centered Instrument Serif hero over a sky-to-hills photograph with sage pages, white rounded cards and bright green actions. Stats become four cards with the third in forest green, image and text alternates between a white card and a lime card by variant, the video section becomes a forest feature card, the project grid becomes horizontal insight cards with a read-more chip, and the FAQ is a centered accordion. The footer ends in a large serif wordmark over drawn green hills. Its Fernflow fixture is fictional.
Business Analytics SaaS
Business Analytics SaaS (business-analytics-saas) uses a white header, a centered Outfit hero with an emerald accent shape and the hero photograph inside a navy product frame with a sidebar pattern. Stats sit in a divided row, feature icons alternate emerald, blue and violet, image and text sits on a mint band with a floating growth card, the logo cloud becomes integration tiles and the price offer becomes a highlighted emerald plan. Testimonials show stars and avatar dots, and the footer is navy. Its Metrova fixture is fictional.
Car Dealership
Car Dealership (car-dealership) uses a deep teal two-row header with a contact utility line, a mint split hero with a rating chip on the vehicle photograph and a white search card overlapping the hero. Image-led service cards become six compact category tiles, image and text becomes a dark teal buy-and-sell band, credentials become centered icon reasons, catalog cards carry a numbered badge, testimonials sit on deep teal, the price offer becomes a mint finance panel and the footer opens with a call to action. Its Corvane Motors fixture is fictional.
Car Rental
Car Rental (car-rental) is a dark theme of near-black green panels with soft borders and lime highlights. A lime strip sits above a centered wordmark and a spaced category navigation; the hero is a bordered photographic card with a large uppercase Archivo heading and lime pill buttons with arrow discs. Credentials become a single feature strip, catalog cards become white rental cards with the middle choice outlined in lime, feature cards become numbered steps and the footer is a bordered panel with a get-in-touch action. Its Laneway Rentals fixture is fictional.
Catering Services
Catering Services (catering-services) uses a forest-green header, cream pages and Gilda Display headings with a leaf divider. The hero places the photograph in an arched frame with a play mark; image service cards sit in a four-column row, feature cards become a forest band with the middle card in olive, image and text pairs a notched photograph with a sand copy card and a signature-style caption, credentials become a crafted menu list, the image slider shows circular dishes on green and the FAQ sits inside a sage card. Its Sage & Table Catering fixture is fictional.
Coaching & Consulting
Coaching & Consulting (coaching-consulting) pairs a navy header and hero with an orange-to-pink-to-violet gradient running through the headline, buttons and a portrait tile with a white name chip. The logo cloud continues the navy hero as a client strip, feature cards carry a gradient underline, stats become a split gradient and navy community panel, service cards gain colored outline badges and arrow buttons, the project grid shows framed step cards, the price offer becomes a dark featured plan and image and text sits in a lilac panel. Its Northbeam Coaching fixture is fictional.
Construction Company
Construction Company (construction-company) uses a floating dark-teal header bar with lime actions over a white page, and a hero whose photograph bleeds to the edge with a slanted cut and a dashed circular stamp. The stats sit in a dark bar overlapping the hero, the third service card turns dark, image and text sits in a sage panel with a parallelogram photograph, the team grid shows four crew portraits, credentials become a numbered dark process panel and the footer is a rounded teal panel with direct contact details. Its Ironleaf Builders fixture is fictional.
Cookie Bakery
Cookie Bakery (cookie-bakery) uses a cream page, a rounded chocolate hero with chunky Lilita One lettering that turns from white to mustard, a circular product photograph and sprinkle dots. Feature cards rotate through peach, pink, sky and butter, the price offer becomes a peach discount panel, product specifications become a dark today’s-special list, image service cards become round product picks, image and text uses a blob-framed photograph with a coral stamp, credentials become a dark service strip and the footer has a scalloped chocolate edge. Its Crumb & Co. Bakery fixture is fictional.
Coworking Space
Coworking Space (coworking-space) pairs a warm off-white page with deep green panels, peach highlights and Gloock serif headlines; the hero heading shifts from green to peach between lines and the workspace photograph sits in a large rounded frame with a green caption card. Credentials become a compact feature strip, feature cards become an icon list, catalog cards share a sand band with the middle card in green, stats run as a green band, gallery figures carry dark captions, testimonials show a portrait tile and lead forms become green form cards with a peach submit. Its Greenhall Workspace fixture is fictional.
Creative Studio Coffee
Creative Studio Coffee (creative-studio-coffee) sets a transparent header and uppercase Bodoni Moda headline that shifts from white to brass over a full-bleed espresso photograph, then moves to latte-beige pages. Credentials become a five-part value strip, the project grid becomes six dark portrait tiles with arrow rings, image and text runs edge to edge with a circular stamp caption, lead forms become a dark roast membership band and the footer is a light, ruled column layout. Its Crema Digital fixture is fictional.
Duck Farm
Duck Farm (duck-farm) keeps white and pale-green pages with deep farm-green panels and sunny yellow highlights. The hero photograph bleeds to the edge and fades into the copy, whose last line turns green, with a handwritten caption. Catalog cards show four products, image and text becomes a dark green panel with a blob-shaped photograph and a dashed natural badge, feature cards become divided trust icons, stats become a dark farming panel, credentials become a numbered farm-to-table process and testimonials sit on cream. Its Brookmead Farm fixture is fictional.
Electrical Services
Electrical Services (electrical-services) pairs a white header with a phone link and a green quote button against charcoal heroes and service cards. The hero photograph fades into charcoal and its last two headline lines turn electric green. Stats sit on a white card that overlaps the hero, image and text cuts its photograph into a hexagon with a round safety badge, service cards turn charcoal with green icon circles, credentials become bolt-marked reasons to choose the company and the CTA becomes a green emergency panel. Its Brightwire Electric fixture is fictional.
Fashion Store Lavender
Fashion Store Lavender (fashion-store-lavender) combines a charcoal masthead and split hero with an arched lilac photograph, Cormorant Garamond headings and warm ivory pages. A lavender benefits strip leads into image-led editorial collections, understated arrival cards and a dark fashion campaign panel. The theme owns all ten page templates, styles all thirty shared sections and supports the seven existing request forms. Navigation links, parents and More share lavender hover and selected states, including when a child page is selected. More and mobile menus use full-width rows with nested links below their parent. Catalog search, native nested navigation, keyboard tabs and image sliders retain the platform contracts. The Violette Edit fixture is fictional; the collection uses enquiry links rather than a shopping basket or checkout.
9. What happens from template activation to publishing?
- Install/activate the template. Eyivo validates the package, records its key/version and exposes its settings and component schemas in the App.
- Choose a page type. Eyivo uses the active theme’s matching Liquid file and area definition when present, otherwise the matching
theme-corefallback. - Add permitted sections. The App only offers the types listed in
allowed_components. It stores text, media references and translations against the selected component instance. - Render safely. Eyivo resolves company/page/SEO/navigation data, renders saved area components, renders direct components where the designer placed them, then renders the active theme’s page type and layout.
- Publish. The visitor receives your HTML and CSS, but no database credentials, internal models or application code.
10. Validation and common mistakes
| If you see… | Check this first |
|---|---|
| “Unsupported Eyivo Theme API version” | Set "eyivo_theme_api": "1.0". |
| Missing page type/layout/component error | Every page type or component declared by the theme needs its matching .liquid file. The active theme must always provide layouts/default.liquid; omitted built-in page types fall back to core. |
| Component unavailable in the editor | Its namespaced type must be in that area’s allowed_components list, or the definition must be universal. |
| Unknown direct component | Use a quoted eyivo: type from the shared catalog or declare a matching theme: definition and Liquid file in the active theme. |
| Field is rejected | Declare it in the component schema and use one supported field type. Use translatable: true for locale-specific text. |
| Template appears unstyled | Use the asset_url filter for CSS and confirm the file is under assets/. |
| Package is rejected for unsafe syntax | Remove PHP/Blade, env, config, DB/HTTP calls and filesystem access. Liquid is presentation-only. |
11. FAQ
Can a customer create a new layout or move a hero below the footer?
No. They can change approved content and order approved components within an area. The Liquid page type owns layout.
Can a designer use a component without an editable area?
Yes. Use eyivo_component in a layout or page type. Use an area when the site owner should control the component instance and its order.
Must a theme implement every page type?
Blog support is required for every theme. The built-in types blog, blog_category, and blog_post can use the matching definitions and Liquid files from theme-core, inside the active theme’s layout. Declare a type only when supplying its matching override file. Existing theme packages remain compatible. Blog routes use /blog, /blog/category/{slug}, and /blog/{slug}, with Eyivo’s locale prefix where required. Preserve eyivo_head for safe metadata, responsive blog styles, and bounded image cards.
Can a theme query a page, call an API or read an environment variable?
No. Data is deliberately passed in as safe objects. This keeps themes portable, secure and predictable.
How do I release an update?
Publish a new semantic theme version. Do not silently mutate a published release; sites should move to a new version explicitly.
Where should images live?
Use an Eyivo media URL in component data, or a package asset referenced through asset_url. Do not use arbitrary server filesystem paths.