Front-Office — Beyond Spec Inventory
This document lists every feature present in thecms-fo codebase (v0.12.6) that is not required by the Next-Generation CMS — Technical Architecture specification (V0.1, October 2025).
The spec defines the FO as a public-facing SSR rendering layer consuming the CMS API. The following features extend that scope significantly.
Companion documents:
FO Coverage Analysis (spec-required gaps) and
FO Roadmap (path to v1.0).
1. Visual Page Builder
Scope: A full no-code homepage editor embedded in the FO, normally a Back-Office concern.| Component | File(s) | Purpose |
|---|---|---|
| BuilderMain | components/builder/BuilderMain.vue | Root builder orchestrator |
| BuilderCanvas | components/builder/BuilderCanvas.vue | Drop-target rendering surface |
| BuilderPreview | components/builder/BuilderPreview.vue | Live preview pane |
| BuilderProperties | components/builder/BuilderProperties.vue | Property editor sidebar |
| BuilderSidebar | components/builder/BuilderSidebar.vue | Block palette / tree |
| BuilderToolbar | components/builder/BuilderToolbar.vue | Undo/redo, save, import/export |
| BuilderTemplates | components/builder/BuilderTemplates.vue | Template picker |
| BuilderTemplateAdapter | components/builder/BuilderTemplateAdapter.vue | Template-to-block adapter |
| HomepageBlockBuilder | components/builder/HomepageBlockBuilder.vue | Homepage-specific builder |
| CustomBlocksBuilder | components/builder/CustomBlocksBuilder.vue | Custom block editor |
| SaveBlockModal | components/builder/SaveBlockModal.vue | Save block to library |
| ImportExportModal | components/builder/ImportExportModal.vue | JSON import/export |
| BlockTreeNode | components/builder/BlockTreeNode.vue | Block tree visualization |
| DropZone / DropIndicator | components/builder/Drop*.vue | Drag-and-drop targets |
| PropertyField* | components/builder/PropertyField*.vue | Field editors (text, multilang, richtext) |
| ValidationIndicator | components/builder/ValidationIndicator.vue | Per-block validation status |
| AutoSaveIndicator | components/builder/AutoSaveIndicator.vue | Save status badge |
useDragAndDrop.ts— Drag-and-drop operationsuseDragState.ts— Drag state managementuseBlockLibrary.ts— Block type registry and metadatauseSavedBlocks.ts— localStorage-based saved blocksuseBuilderValidation.ts— Block composition rules
stores/builder.ts — Pinia/useState store with undo/redo history, block CRUD, import/export.
Pages: pages/blocs/index.vue, pages/blocs/preview/[type].vue — Builder UI and preview routes.
Utilities:
utils/builder-helpers.ts— Builder utility functionsutils/composition-validator.ts— Validate block nesting rulesutils/atom-validator.ts,utils/atom-rules.ts— Atom block constraintsutils/field-schemas.ts— Property field schema definitionsutils/form-defaults.ts— Default values per block typeutils/blocks-mock-data.ts— Mock data for all block typesutils/default-template-blocks.ts— Default block configurations per template
2. Atom Component Library
Scope: 27 reusable UI primitives used by dynamic blocks and the builder.| Category | Components |
|---|---|
| Layout | Container, Flex, Grid, Group, Stack, Spacer |
| Typography | Text, Link |
| Media | Image, Avatar, Icon |
| Actions | Button, Badge, Rating |
| Cards | Card |
| Dividers | Divider |
| Forms | Form, FormField, FormInput, FormLabel, FormCheckbox, FormRadio, FormSelect, FormTextarea, FormStep, FormStepper |
| Feedback | SkeletonLoader |
components/atoms/*.vue
Maturity: 95% — Complete, typed, used across the block system.
3. Block Multi-Variant System
Scope: Each block type can have multiple visual variants per template and per structure, with automatic resolution.| Block type | Variant directory | Templates supported |
|---|---|---|
| Carousel | components/dynamic-blocks/carousel/ | Default, Aurora, Canvas, Nordic |
| Countdown | components/dynamic-blocks/countdown/ | Default, Aurora, Canvas, Nordic |
| CTA | components/dynamic-blocks/cta/ | Default, Aurora, Canvas, Nordic |
| Features | components/dynamic-blocks/features/ | Default, Aurora, Canvas, Nordic |
| Hero | components/dynamic-blocks/hero/ | Default, Aurora, Canvas, Nordic |
| TextImage | components/dynamic-blocks/text_image/ | Default, Aurora, Canvas, Nordic |
useBlockVariant.ts— ReadsvariantTemplate+variantStructurefrom block configvariantResolver.ts— Lookup table mapping(blockType, template, structure)→ componentBlockTemplateWrapper.vue— Wraps resolved component with template-specific CSS class
4. Design Token Engine
Scope: A complete token-based theming system with palette generation, 4 built-in templates, dark mode, and cross-tab synchronization. The spec mentions a “Design-Token System” as an area extending the platform (section 6.2), but the implementation far exceeds what was described.4.1 Token architecture
| Layer | File(s) | Description |
|---|---|---|
| Base colors | tokens/templates/*.json | 6 color families (primary, secondary, success, warning, error, neutral) |
| Palette generation | utils/paletteGenerator.ts | Generates 50–950 shade scales from base colors |
| Semantic tokens | utils/semanticTokensGenerator.ts | Maps palette → intent tokens (primaryBg, textMuted, borderDefault, surfaceElevated, etc.) |
| CSS variable output | utils/theme-css-generator.ts | Generates --token-* CSS custom properties |
| Inline injection | utils/inlineTokensCSS.ts | Critical-path inline CSS for SSR |
| Build-time generation | scripts/generate-design-tokens.mjs | Pre-generates .generated.css files per template |
4.2 Token categories
| Category | Examples |
|---|---|
| Colors | --token-color-primary-500, --token-color-neutral-100 |
| Semantic | --token-semantic-primaryBg, --token-semantic-textMuted |
| Typography | --token-font-family, --token-font-size-base, --token-line-height |
| Spacing | --token-spacing-gap, --token-spacing-padding |
| Radius | --token-radius-sm, --token-radius-lg |
| Shadow | --token-shadow-sm, --token-shadow-lg |
| Border | --token-border-width |
| Layout | --token-layout-max-width, --token-layout-gutter |
| Motion | --token-motion-duration-fast, --token-motion-duration-slow |
4.3 Template implementations
| Template | CSS file | Token file | Visual style |
|---|---|---|---|
| Default | templates-default.css | tokens.default.generated.css | Tailwind-like, balanced |
| Aurora Pulse | templates-auroraPulse.css | tokens.auroraPulse.generated.css | Vibrant, gradient-heavy |
| Nordic Ledger | templates-nordicLedger.css | tokens.nordicLedger.generated.css | Minimal, professional |
| Canvas Mosaic | templates-canvasMosaic.css | tokens.canvasMosaic.generated.css | Grid-based, artistic |
4.4 Theme composable
composables/useTheme.ts — 1,893 lines. Manages template selection, dark mode, RTL, token application, draft edits, BroadcastChannel sync, sessionStorage caching.
Maturity: 98% — Exceptionally complete. Dark mode, cross-tab sync, SSR injection, draft system all working.
5. Dark Mode
Scope: Full dark mode support via design tokens.| Feature | Implementation |
|---|---|
| Toggle | useTheme().toggleDarkMode() / setDarkMode(bool) |
| Persistence | localStorage key STORAGE_KEY_DARK_MODE |
| CSS | .dark class on <body>, dark semantic tokens applied |
| Cross-tab sync | BroadcastChannel theme-cache-sync |
| Token generation | Separate dark palette in semanticTokensGenerator.ts |
6. RTL Support
Scope: Right-to-left layout support for Arabic and similar languages.| Feature | Implementation | Status |
|---|---|---|
| State management | useTheme().setRtl(bool) | Working |
| Auto-detection | Arabic locale → rtl: true | Working |
| HTML attribute | dir="rtl" on <html> via app.vue | Working |
| CSS flipping | No RTLcss or logical properties | Missing |
RTLcss or migration to CSS logical properties (margin-inline-start instead of margin-left).
7. Advanced Caching (3-Layer ETag)
Scope: A sophisticated client+server caching system far beyond what the spec requires.| Layer | Location | TTL | Scope |
|---|---|---|---|
| Nitro storage (Redis/memory) | Server-side | Configurable | Shared between SSR requests |
| In-memory Map | utils/cache.ts | Per-entry TTL | Per-process |
| localStorage | utils/cache.ts | Per-entry TTL, max 5 MB | Per-browser |
- ETag /
If-None-MatchHTTP validation (RFC 7232) - Request priority system (critical / high / normal / low) with adaptive timeouts (2s SSR, 10s client)
- Connection error recovery with 1s cooldown cache
- Stale-while-revalidate fallback when API is down
- Exponential backoff retry (1s → 2s → 5s, max 2 retries client-side, 0 SSR)
returnEmptyOnConnectionErroroption for graceful degradation- Cache metrics via
getCacheStats()
utils/api.ts (817 lines), utils/cache.ts (427 lines), utils/request-priority.ts
Maturity: 95% — Battle-tested, well-commented, comprehensive error handling.
8. Unlayer HTML Parser
Scope: Parses Unlayer (drag-and-drop email builder) HTML output into CMS block configurations. Files:utils/unlayerParser.ts (1,039 lines), utils/unlayerSanitize.ts
Features:
- Dual-mode parsing: DOM-based (client) + regex-based (SSR)
- Extracts
data-cms-blockanddata-cms-configattributes - Cleans Unlayer markup (
u_row,u_column,u_content_html) - Removes Unlayer preview UI elements
- Placeholder deduplication and overlap detection
9. Performance Optimizations
Scope: Multiple performance features beyond basic SSR.| Feature | File(s) | Description |
|---|---|---|
| Blurhash placeholders | utils/blurhash.ts | Generates CSS gradient placeholders from blurhash strings. Low-resolution image preview during load. |
| Lazy hydration | composables/useLazyHydration.ts, utils/hydration-strategy.ts | 3 strategies: on-visible (IntersectionObserver), on-idle (requestIdleCallback), on-interaction (click/hover/focus) |
| Above-fold detection | composables/useAboveFold.ts | Detect if component is above the fold for priority loading |
| Delay hydration | nuxt.config.ts → nuxt-delay-hydration | Defer full hydration by 2s in production, replay clicks |
| CSS optimization | nuxt.config.ts → nuxt-vitalizer | Disable blocking entry CSS in production |
| Vendor splitting | nuxt.config.ts → manualChunks | 9 vendor chunks: vue, router, i18n, flowbite, charts, drag, masonry, image, other |
| Font optimization | @nuxt/fonts | Self-hosted fonts with font-display: swap |
| Image optimization | @nuxt/image | AVIF/WebP/JPEG/PNG format priority, responsive screens config |
| Preconnect hints | app.vue → useHead | Preconnect to API, media, Google Fonts |
| Cache metrics page | pages/cache-metrics.vue, composables/useCacheMetrics.ts | Debug page showing cache hit/miss rates |
10. Form System
Scope: A complete form infrastructure including stepper, validation, and submission (currently disabled).| Component | File(s) |
|---|---|
| Form composable | composables/useContactForm.ts, composables/useFormSubmit.ts, composables/useForm.ts |
| Validation | utils/form-validation.ts |
| Defaults | utils/form-defaults.ts |
| Atoms | 9 form components in components/atoms/Form*.vue |
| Blocks | FormBlock, ContactFormBlock, NewsletterSignupBlock, FormFieldBlock, FormInputBlock, etc. |
useContactForm.ts returns false immediately with a TODO comment: “Contact form submission is disabled - endpoint not implemented yet”.
Maturity: 60% — Infrastructure complete, endpoint missing.
11. Extra Content Types
Scope: Content types beyond the spec’s pages / articles / categories / tags.| Content type | Route | Notes |
|---|---|---|
| Gallery | pages/gallery/[slug].vue | Gallery detail page |
| Events | pages/events/[slug].vue | Event detail page |
| Archive | pages/archive/[year]/[month].vue | Date-based archive |
12. Cross-Tab Synchronization
Scope: BroadcastChannel API for real-time sync across tabs and iframes.| Channel | Purpose | Files |
|---|---|---|
theme-cache-sync | Theme/dark mode changes | composables/useTheme.ts |
site-settings-cache-sync | Settings invalidation | composables/useSiteSettings.ts |
window.addEventListener('storage', ...) for browsers without BroadcastChannel.
Extra features in useSiteSettings:
- Polling every 30 seconds for server changes
- Refresh on
window.focus - Custom events:
theme-cache-invalidated,site-settings-cache-invalidated
13. Prerender Routes Plugin
Scope: Dynamic route discovery from the CMS API at build time. Files:server/plugins/prerender-routes.ts, server/utils/prerender-helper.ts (233 lines)
Features:
- Fetches all published pages, articles, categories, tags from the API
- Generates prerender routes for Nitro SSG
- Handles multilingual slugs (string and object formats)
- Pagination support (100 items per page)
- 30s timeout per API call
- Graceful fallback if API is unreachable
14. Security Extras
Scope: Security features beyond the spec’s CSP requirement.| Feature | File(s) | Description |
|---|---|---|
| Authorization header logging | server/api/log/authorization.post.ts | Logs attempts to send Authorization headers on public endpoints. Stores to log/authorization/YYYY-MM-DD.json. Max 1,000 entries per file. |
| Preview anti-unfurl | server/middleware/preview-anti-unfurl.ts | Blocks 12+ social media bots (Slack, Twitter, Facebook, Discord, etc.) from accessing preview URLs. Returns 403. |
| HTML sanitization | utils/sanitizeInlineHtml.ts | Sanitizes user-provided HTML in blocks |
| Public header validation | utils/api.ts → validatePublicHeaders() | Ensures no Authorization header leaks in public API calls |
15. E2E Test Suite
Scope: Versioned end-to-end test suite covering every major FO feature.| Test file | Scope |
|---|---|
v0.1-spec.ts | Core routing |
v0.2-spec.ts | i18n multilingual |
v0.3-spec.ts | Preview mode |
v0.4-spec.ts | Security (403 handling) |
v0.5-spec.ts | API configuration |
v0.6-spec.ts | Cache mechanics |
v0.7-spec.ts | Image optimization |
v0.8-spec.ts | Homepage blocks |
v0.9-spec.ts | Performance |
v0.10-spec.ts | Advanced API patterns |
v0.11-spec.ts | Dynamic blocks + Unlayer |
v0.12-spec.ts | ETag caching |
performance.spec.ts | Performance benchmarks |
consolidated.spec.ts | Regression suite |
16. Storybook
Scope: Component documentation infrastructure. Files:.storybook/main.ts, .storybook/preview.ts
State: Configured (Storybook 8.6, Vue3-Vite framework) but no stories written. Placeholder infrastructure only.
Maturity: 10%.
17. Template Manifest System & Design Token Contract
Scope: A formal architectural contract and a typed manifest system that governs the design-token pipeline and template definitions. Not mentioned in the spec.17.1 Design Token Contract
File:DESIGN_TOKENS_CONTRACT.md (100 lines)
Defines the golden rules for color management:
- Single source of truth:
baseColors→palette(50–950) →semantic tokens→ CSS variables - Build-time generation vs runtime override paradigm
- Strict accessibility constraints (contrast ratios)
- No raw hex values allowed in components — only token references
17.2 Template Manifests
| File | Template | Sections defined |
|---|---|---|
src/templates/index.ts | Registry (38 lines) | Exports TEMPLATE_MANIFESTS, TEMPLATE_CATALOG, TEMPLATE_OPTIONS, getTemplateManifest() |
src/templates/default.ts | Default (76 lines) | 5 sections: nav, hero split, content columns, CTA, footer |
src/templates/auroraPulse.ts | Aurora Pulse (100 lines) | 7 sections: nav, hero, editorial grid, carousel, testimonials, CTA, footer |
src/templates/canvasMosaic.ts | Canvas Mosaic (107 lines) | 8 sections: compact nav, mosaic hero, masonry grid, alternating stories, gallery, testimonials, CTA, footer |
src/templates/nordicLedger.ts | Nordic Ledger (89 lines) | 6 sections: side nav, hero split with stats, content columns, metrics bar, CTA, footer |
18. Token Editor Components
Scope: Interactive components for editing design tokens in the browser — part of the design system tooling.| Component | File | Lines | Purpose |
|---|---|---|---|
| A11yStatus | components/tokens/A11yStatus.vue | 213 | WCAG contrast report viewer, suggestion applicator, expert override toggle |
| TokenColorPicker | components/tokens/TokenColorPicker.vue | 126 | Native HTML color picker for base color editing, emits hex values |
| TokenSlider | components/tokens/TokenSlider.vue | 194 | Dual-input (range + number) for spacing/sizing tokens, with recommended value hints |
- Displays contrast reports per palette shade
- Suggests accessible color alternatives
- “Non-accessible mode” toggle for expert override (skips contrast checks)
- Emits events for mode toggling and fix application
19. Block Management Tool
Scope: A secondary block management UI incomponents/blocs/ — distinct from the components/builder/ visual builder. Used as an internal admin tool for zone-based block editing.
| Component | File | Lines | Purpose |
|---|---|---|---|
| HomepageBlockBuilder | components/blocs/HomepageBlockBuilder.vue | 216 | Block structure orchestrator with template selection and config modal |
| BlockZonesEditor | components/blocs/BlockZonesEditor.vue | 456 | Zone-based editor (sidebar, content, right_sidebar) with drag-and-drop reordering |
| BlockConfigEditor | components/blocs/BlockConfigEditor.vue | 681 | Modal for editing block configs: checkbox, select, input, text fields with accessible keyboard nav |
components/builder/):
- Zone-based (sidebar / content / right_sidebar) rather than free-form canvas
- Simpler, admin-oriented UI
- Extensive debug logging
- Direct block CRUD events rather than undo/redo history
20. Client-Side Plugins Suite
Scope: Four client-side Nuxt plugins that extend runtime behavior well beyond the spec.20.1 i18n Locale Prefix Blocking
File:plugins/block-i18n-redirects.client.ts (106 lines)
Prevents navigations to language prefixes (/en, /fr, /nl) when the no_prefix strategy is used. Installs a beforeEach router guard and cleans initial paths.
20.2 Critical CSS Injection
File:plugins/critical-css.ts (75 lines)
Injects inline critical CSS in <head> during SSR for FCP optimization. Contains above-the-fold reset, flexbox utilities, typography base, focus-visible, and font-display: swap.
20.3 Design Tokens Client Initialization
File:plugins/design-tokens.client.ts (254 lines)
Loads design tokens from localStorage (user overrides) and the API (non-default templates) at page load. Does not execute in iframes (defers to preview-tokens plugin).
20.4 Preview Tokens (iframe)
File:plugins/preview-tokens.client.ts (365 lines)
Listens to postMessage events inside the preview iframe and applies tokens dynamically. Handles three message types: apply-tokens, apply-template, reload-fonts. Double-verified (iframe detection + preview-template param).
Combined maturity: 90% — All plugins are production-ready. Critical CSS could be automated from Lighthouse data.
21. Developer Utilities & Build Scripts
Scope: Supporting utilities and scripts that improve DX and build reliability.21.1 Google Fonts Dynamic Loader
File:utils/googleFonts.ts (58 lines)
Dynamically loads Google Fonts in preview iframes. Generates API URLs, extracts font names, manages DOM <link> elements.
21.2 Toast Notification System
File:composables/useNotifications.ts (104 lines)
Toast notification composable: show(), success(), error(), warning(), info(), remove(), clear(). Auto-dismissal timer. Replaces raw console.error with user-visible feedback.
21.3 i18n Normalization Utilities
File:utils/i18n.ts (100 lines)
Normalizes locales and multilingual values: normalizeLocale(), normalizeMultilingualValue(), getLocalizedValue(). Handles nested structures and fallback chains.
21.4 Content Configuration API
File:composables/useContentConfig.ts (90 lines)
Fetches content configuration from the API with graceful defaults. Used for article pagination settings. Extensible to other content types.
21.5 URL Mapper
File:utils/urlMapper.ts (102 lines)
Maps 18 URL types (placeholders, social, branding) using runtime config. Provides getPlaceholderImage(), getPlaceholderAvatar(), getPlaceholderBackground() with seeded randomization.
21.6 Debug Utilities
File:utils/debug.ts (58 lines)
Conditional debug logging: debugLog(), debugError(), debugWarn(). Respects NUXT_DEBUG_API flag and reduces SSR log noise.
21.7 Dual Preview Mode System
Two separate composables for preview:composables/usePreview.ts(40 lines) — Token-based: readspreview_tokenfrom query, providesgetPreviewHeaders()composables/useIsPreviewMode.ts(15 lines) — Boolean: reads?preview=truequery param
usePreview is for API-authenticated preview, useIsPreviewMode is for UI-only preview toggling.
21.8 Build Scripts
| Script | File | Lines | Purpose |
|---|---|---|---|
| Block Change Detection | scripts/detect-block-changes.mjs | 305 | Compares block files against .build/blocks-reference.json using SHA-256 hashes. Reports added/modified/removed/unchanged blocks. |
| Template Selector Injection | scripts/add-block-template-selectors.mjs | 39 | Adds [data-block-template="X"] attribute selectors to CSS files alongside body.template-X. |
21.9 Layout & Scaffold
| File | Lines | Purpose |
|---|---|---|
layouts/plain.vue | 5 | Minimal layout — renders slot without wrapper. Used for preview/embed pages. |
components/templates/SiteScaffold.vue | 72 | Template-aware scaffold: Header, Footer, conditional Nordic sidebar navigation, responsive layout. |
21.10 Saved Blocks Library
File:composables/useSavedBlocks.ts (149 lines)
localStorage-based block library for the builder: saveBlock(), updateSavedBlock(), deleteSavedBlock(), searchSavedBlocks(). Supports tagging and search.
Combined maturity: 85% — All utilities are functional. Dual preview system should be consolidated.
Summary
| # | Feature | Category | Maturity | Business value |
|---|---|---|---|---|
| 1 | Visual Page Builder | Authoring | 85% | High — enables no-code editing |
| 2 | Atom Component Library | Design system | 95% | Medium — internal reuse |
| 3 | Block Multi-Variant System | Design system | 85% | High — template flexibility |
| 4 | Design Token Engine | Design system | 98% | High — theming foundation |
| 5 | Dark Mode | UX | 95% | Medium — user preference |
| 6 | RTL Support | i18n | 40% | Low (no Arabic tenants yet) |
| 7 | Advanced Caching (3-Layer) | Performance | 95% | High — resilience + speed |
| 8 | Unlayer HTML Parser | Authoring | 90% | Medium — builder dependency |
| 9 | Performance Optimizations | Performance | 85% | High — Core Web Vitals |
| 10 | Form System | Content | 60% | Medium — blocked by API |
| 11 | Extra Content Types | Content | 50% | Low — needs API support |
| 12 | Cross-Tab Synchronization | UX | 95% | Medium — multi-tab editing |
| 13 | Prerender Routes Plugin | Performance | 90% | High — SSG completeness |
| 14 | Security Extras | Security | 85% | Medium — defense-in-depth |
| 15 | E2E Test Suite | Quality | 85% | High — regression safety |
| 16 | Storybook | DX | 10% | Low — unused |
| 17 | Template Manifest System & Token Contract | Architecture | 90% | High — governs theming |
| 18 | Token Editor Components | Design system | 80% | Medium — internal tooling |
| 19 | Block Management Tool | Authoring | 75% | Medium — admin interface |
| 20 | Client-Side Plugins Suite | Runtime | 90% | High — perf + UX |
| 21 | Developer Utilities & Build Scripts | DX | 85% | Medium — DX + build reliability |