Skip to content

Building a Production-Ready WordPress FSE Block Theme: The Moiraine Story

By Jasper Frumau

Introduction: Why We Built a Custom FSE Block Theme

Over the past six months, we’ve been on an intensive journey developing Moiraine, a production-ready Full Site Editing (FSE) block theme for WordPress. This wasn’t just another theme project—it was a deep dive into modern WordPress development, performance optimization, and the Block Editor ecosystem.

At Imagewize, we’ve been building custom WordPress websites for SMEs across the US and Europe for years. But as WordPress evolved from the Classic Editor to the Block Editor (Gutenberg), and finally to Full Site Editing, we realized we needed a theme that could:

  • Deliver blazing-fast performance without expensive page builders
  • Provide design flexibility through reusable block patterns
  • Meet WordPress.org Theme Review requirements for quality and accessibility
  • Support modern development workflows with theme.json and minimal CSS

This post shares what we learned building Moiraine from the ground up—the technical architecture, performance optimizations, accessibility improvements, and the WordPress.org submission process.

What is Full Site Editing (FSE)?

Before diving into the build process, let’s clarify what Full Site Editing actually means in 2026.

The Evolution of WordPress Theming

Classic Themes (Pre-2018):

  • PHP template files (header.php, footer.php, single.php)
  • Functions.php for customization
  • Limited visual editing
  • Required coding knowledge for layout changes

Block Editor Themes (2018-2021):

  • Introduction of Gutenberg block editor
  • Content editing with blocks
  • Templates still PHP-based
  • Hybrid approach

Full Site Editing Themes (2021-Present):

  • HTML template files instead of PHP
  • Visual editing of headers, footers, and templates
  • Global Styles via theme.json
  • Block patterns for reusable layouts
  • Complete design control without code

Why FSE Matters for Modern Web Development

FSE represents a fundamental shift in how WordPress sites are built:

  1. Performance: No heavy page builders (eliminates 500KB+ of JavaScript/CSS)
  2. Maintainability: Standardized block-based architecture
  3. Client Empowerability: Non-technical users can edit entire sites visually
  4. Developer Efficiency: Reusable patterns and centralized theme.json configuration
  5. Future-Proof: WordPress core development is fully committed to FSE

The Moiraine Architecture

Moiraine is built on a foundation of modern WordPress best practices. Here’s the core structure:

Theme Structure

moiraine/
├── assets/
│   └── fonts/              # Self-hosted variable fonts
│       ├── mona-sans/      # Primary font family
│       ├── bodoni-moda/    # Serif option
│       └── Open-Sans.woff2 # Body text
├── patterns/               # 108 block patterns
│   ├── hero-*.php
│   ├── card-*.php
│   ├── testimonial-*.php
│   ├── pricing-*.php
│   └── template-*.php
├── parts/                  # 7 template parts
│   ├── header.html
│   ├── footer.html
│   └── sidebar.html
├── styles/                 # Style variations
│   ├── colors/            # 10 color schemes
│   ├── typography/        # 10 font pairings
│   └── [variations].json  # 6 complete variations
├── templates/             # 8 HTML templates
│   ├── index.html
│   ├── single.html
│   └── page.html
├── functions.php          # Minimal setup
├── theme.json            # Core configuration
└── style.css             # Theme metadata + reset

Key Design Decisions

1. theme.json as Single Source of Truth

Rather than scattering styles across multiple CSS files, we centralized configuration in theme.json:

  • Color palette: 11 semantic colors (primary, base, contrast, borders)
  • Typography: 7 fluid font sizes with min/max responsive scaling
  • Spacing: 7 preset spacing scales using clamp() for fluid sizing
  • Shadows: 8 shadow presets (4 dark, 4 light variants)
  • Custom properties: Font weights, line heights, layout widths

This approach reduces CSS bloat and ensures consistency across all blocks and patterns.

2. Variable Font Implementation

We implemented Mona Sans, a variable font that supports:

  • Font weight range: 300-900
  • Font stretch: 75%-125%
  • Single WOFF2 file for all weights and widths

This replaced traditional font loading that would require 10+ font files, reducing HTTP requests and improving performance.

3. Fluid Typography and Spacing

Every font size and spacing value uses CSS clamp() for truly responsive design:

{
  "fontSize": {
    "fluid": {
      "min": "1.5rem",
      "max": "2.75rem"
    },
    "size": "2.75rem",
    "slug": "large"
  }
}

This eliminates the need for media query breakpoints—text scales smoothly from mobile to desktop.

Building 108+ Block Patterns

Block patterns are Moiraine’s superpower. They’re pre-designed block layouts that users can insert with a single click.

Pattern Categories We Built

  1. Hero Sections (8 patterns)
    • Call-to-action with buttons
    • Text and image combinations
    • Large text hero variations
  2. Card Layouts (12 patterns)
    • Blog post cards
    • Pricing tables
    • Contact cards
    • Call-to-action cards
  3. Testimonials (6 patterns)
    • With social links
    • With large quotes
    • Logo grids with testimonials
  4. Features & Benefits (8 patterns)
    • Icon boxes
    • Number statistics
    • Text and image columns
  5. Pricing Tables (4 patterns)
    • 2-column and 3-column layouts
    • Feature comparison grids
  6. Full Page Templates (7 patterns)
    • Blog archive pages
    • Contact pages
    • Pricing pages
    • 404 error pages
  7. Headers & Footers (15 patterns)
    • Dark and light variations
    • Mobile menu patterns
    • Mega menu integration

Pattern Development Workflow

Each pattern is a PHP file that registers block markup:

<?php
/**
 * Title: Hero Call to Action with Buttons
 * Slug: moiraine/hero-call-to-action-buttons
 * Categories: moiraine-hero
 * Viewport Width: 1280
 */
?>

<!-- wp:group -->
<div class="wp-block-group">
    <!-- Block markup here -->
</div>
<!-- /wp:group -->

Pattern Development Tips:

  • Use semantic color names (primary, base, contrast) not hex codes
  • Reference preset spacing values from theme.json
  • Avoid hardcoded font sizes—use preset slugs
  • Test patterns at mobile and desktop widths
  • Include viewport width for accurate pattern previews

Custom Block Development: The Moiraine Blocks Plugin

WordPress.org Theme Review guidelines prohibit themes from registering custom blocks. This makes sense—blocks should be portable between themes.

We created the Moiraine Blocks companion plugin with three custom blocks:

1. Mega Menu Block

Purpose: Advanced navigation with dropdown panels and template part integration.

Technical Implementation:

  • Built with @wordpress/scripts build tooling
  • Uses WordPress Interactivity API for dropdown behavior
  • Supports template parts for mega menu content
  • Keyboard navigation compliant (ARIA patterns)
  • Mobile-responsive with touch/swipe support

Why We Built It:

Standard WordPress navigation blocks don’t support complex mega menus with multi-column layouts, images, and rich content. Our mega menu block lets users:

  • Insert any template part as a dropdown panel
  • Create product showcases in navigation
  • Build feature-rich menus without custom code

2. Carousel Block

Purpose: Responsive image/content slider with Slick Carousel integration.

Technical Implementation:

  • Parent block that wraps multiple slides
  • Slick Carousel library for slide functionality
  • Customizable settings (autoplay, arrows, dots, speed)
  • Responsive breakpoints for mobile/tablet/desktop

Use Cases:

  • Client testimonial carousels
  • Portfolio/case study showcases
  • Product image galleries
  • Logo sliders

3. Slide Block

Purpose: Individual carousel slides with InnerBlocks support.

Technical Implementation:

  • Uses WordPress InnerBlocks API
  • Allows any block combination inside slides
  • Seamless integration with parent Carousel block

Flexibility:

Users can build slides with any combination of:

  • Images, headings, paragraphs
  • Buttons and call-to-actions
  • Testimonials with attribution
  • Custom HTML or embeds

theme.json: The Heart of Modern WordPress Themes

The 927-line theme.json file is Moiraine’s configuration center. Let’s break down the key sections:

Settings Section

Defines available design tools and options:

{
  "settings": {
    "appearanceTools": true,
    "color": {
      "defaultPalette": false,
      "palette": [
        {
          "name": "Brand",
          "slug": "primary",
          "color": "#5344F4"
        }
      ]
    },
    "typography": {
      "fluid": true,
      "fontFamilies": [...]
    },
    "spacing": {
      "spacingSizes": [...]
    }
  }
}

Key Configuration Decisions:

  • defaultPalette: false — Removes WordPress default colors for cleaner interface
  • defaultGradients: false — Custom gradients only
  • fluid: true — Enables fluid typography scaling
  • useRootPaddingAwareAlignments: true — Better full-width alignment

Styles Section

Applies default styles to blocks and elements:

{
  "styles": {
    "elements": {
      "button": {
        "border": {
          "radius": "5px"
        },
        "color": {
          "background": "var:preset|color|main",
          "text": "var:preset|color|base"
        },
        "typography": {
          "fontSize": "var:preset|font-size|small",
          "fontWeight": "500"
        }
      }
    }
  }
}

This eliminates the need for custom CSS—buttons automatically get consistent styling across the entire site.

Block-Specific Styles

We customized 20+ core blocks directly in theme.json:

  • Navigation: Link hover effects, font weight
  • Quote/Pullquote: Border styles, citation formatting
  • Code/Preformatted: Background colors, padding, monospace font
  • Comments: Author name, date, reply link styling
  • Post Template: Heading sizes in loops

Custom Templates and Template Parts

theme.json also registers available templates and their purposes:

{
  "customTemplates": [
    {
      "name": "page-no-title",
      "title": "Page (Full Width, No Title)",
      "postTypes": ["page", "post"]
    }
  ],
  "templateParts": [
    {
      "name": "header",
      "area": "header"
    }
  ]
}

Performance Optimization Strategies

Moiraine was built with performance as a primary goal. Here’s what we implemented:

1. Zero Page Builder Bloat

Problem: Page builders like Elementor or WPBakery add 500KB-2MB of assets.

Solution: FSE blocks are native to WordPress core—no additional JavaScript framework needed.

Result: Moiraine adds only ~25KB of CSS (including reset and custom styles).

2. Self-Hosted Variable Fonts

Problem: Google Fonts requires external HTTP requests and privacy concerns (GDPR).

Solution: Self-hosted WOFF2 variable fonts with font-display: block/swap.

Result:

  • Zero external font requests
  • Single font file loads all weights (300-900)
  • Font subsetting reduces file size by 60%

3. Minimal JavaScript Usage

JavaScript Loaded:

  • WordPress core blocks: ~85KB (gzipped)
  • Mega Menu Interactivity API: ~8KB
  • Slick Carousel (when carousel block used): ~15KB

JavaScript NOT Loaded:

  • jQuery (not used anywhere)
  • Animation libraries
  • Page builder frameworks

4. CSS Architecture

style.css contains only:

  • CSS reset (normalize.css approach)
  • Form standardization
  • Accessibility enhancements
  • Mobile responsive helpers

All design styles come from theme.json, which WordPress converts to inline CSS on page load—highly optimized and cacheable.

5. Image Optimization Ready

Moiraine fully supports WordPress 5.5+ features:

  • Lazy loading (native)
  • WebP image format
  • Responsive image srcset
  • Aspect ratio preservation

Need help with WordPress speed optimization? We offer professional performance optimization services for SMEs.

Accessibility: Building for Everyone

Accessibility was non-negotiable. We implemented WCAG 2.1 AA standards throughout.

Keyboard Navigation

Navigation Menus:

  • Full keyboard support (Tab, Enter, Escape, Arrow keys)
  • ARIA attributes for screen readers
  • Focus visible states on all interactive elements

Mega Menu Accessibility:

.skip-link:focus {
  background-color: var(--wp--preset--color--primary);
  outline: 3px solid var(--wp--preset--color--main);
  z-index: 100000;
  /* Visible skip link on keyboard focus */
}

Color Contrast

All color combinations tested for WCAG AA contrast ratios:

  • Text on backgrounds: Minimum 4.5:1
  • Large text: Minimum 3:1
  • Buttons and interactive elements: 4.5:1

Semantic HTML

  • Proper heading hierarchy (h1 → h6)
  • Landmark regions (header, nav, main, footer)
  • Form labels associated with inputs
  • Alt text requirements for images

Screen Reader Optimization

  • Skip to content links
  • ARIA labels on icon-only buttons
  • Focus management in modals/dropdowns
  • Descriptive link text (no “click here”)

WordPress.org Theme Submission Process

Submitting to the WordPress.org Theme Directory was an intensive learning experience. Here’s what we went through:

Pre-Submission Requirements

Theme Check Plugin: Must pass all required checks

  • No PHP errors or warnings
  • Proper text domain usage
  • Required theme files present
  • Security best practices (escaping, sanitization)

Theme Unit Test: Import and test with sample content

  • All post formats display correctly
  • Comments system works
  • Pagination functions
  • Archive pages render properly

Accessibility Audit:

  • Keyboard navigation works everywhere
  • Color contrast meets WCAG AA
  • Skip links functional
  • Screen reader friendly

Initial Submission Feedback

Our first submission received detailed feedback on:

  1. Documentation Requirements
    • Added comprehensive README.md
    • Created screenshot.png showing theme design
    • Documented all third-party resources
  2. Code Quality Issues
    • Fixed variable naming conventions
    • Removed unused functions
    • Improved inline documentation
  3. Licensing Clarity
    • Listed all font licenses (SIL Open Font License)
    • Documented image sources
    • Added GPL license headers
  4. Security Hardening
    • Escaped all output (esc_html, esc_url, esc_attr)
    • Sanitized inputs
    • Used nonces for form submissions

Iterative Review Rounds

Round 1: Documentation and licensing issues
Round 2: Accessibility improvements needed
Round 3: Code cleanup and best practices
Round 4: Final security review
Round 5: Approval!

Timeline: ~6 weeks from initial submission to approval

Lessons Learned

  • Start with Theme Check plugin early — don’t wait until submission
  • Test with Theme Unit Test data — reveals edge cases
  • Document everything — licenses, credits, resources
  • Follow WordPress Coding Standards — use PHP_CodeSniffer
  • Accessibility is non-negotiable — test with keyboard and screen readers

Style Variations: Design Flexibility at Scale

Moiraine includes 6 complete style variations and dozens of mix-and-match options:

Complete Style Variations

  1. Default (Moiraine) — Purple brand, modern sans-serif
  2. Agency — Bold typography, high contrast
  3. Consulting — Professional blue, Bodoni serif headings
  4. Creator — Vibrant pink accent, wide headings
  5. Publisher — Editorial style, optimized for reading
  6. Startup — Energetic orange, condensed fonts
  7. Studio — Minimalist, narrow typography

Mix-and-Match Options

Color Schemes (10):

  • Blue, Royal Blue, Teal, Green
  • Pink, Red, Orange, Neon
  • Corporate Blue, Publisher

Typography Presets (10):

  • Various font pairings
  • Sans-serif and serif combinations
  • Condensed, narrow, expanded variations

How It Works:

Each variation is a separate theme.json file that overrides specific settings:

{
  "version": 3,
  "title": "Consulting",
  "settings": {
    "color": {
      "palette": [
        {
          "slug": "primary",
          "color": "#1E3A8A",
          "name": "Professional Blue"
        }
      ]
    }
  }
}

Users can activate variations from Appearance → Editor → Styles, switching entire site designs with one click.

Real-World Performance Metrics

We deployed Moiraine on demo.imagewize.com. Here are the results:

PageSpeed Insights (Mobile)

  • Performance: 95-98/100
  • First Contentful Paint: 0.8s
  • Largest Contentful Paint: 1.2s
  • Total Blocking Time: 0ms
  • Cumulative Layout Shift: 0.01

Lighthouse Scores

  • Performance: 98/100
  • Accessibility: 100/100
  • Best Practices: 100/100
  • SEO: 100/100

Asset Size Analysis

Total Page Weight (Homepage):

  • HTML: 18KB
  • CSS: 28KB (inline from theme.json)
  • JavaScript: 92KB (WordPress core blocks)
  • Fonts: 68KB (variable WOFF2)
  • Images: 145KB (WebP, optimized)

Total: ~351KB (fully loaded homepage)

Compare to typical page builder sites: 2-5MB

Development Workflow and Tools

Local Development Environment

Trellis (Lima-based VM):

  • Ubuntu 24.04 LTS
  • PHP 8.3
  • MariaDB 10.6
  • Nginx web server

Access:

cd ~/code/imagewize.com/trellis
trellis vm shell

Build Tools

Block Development:

cd blocks/mega-menu
npm install
npm run build  # Production build
npm run start  # Development watch mode

Theme Development:

  • No build process needed for theme.json
  • CSS is minimal and hand-written
  • Patterns are pure PHP

Version Control Strategy

Git Workflow:

  • main branch: Production-ready releases
  • develop branch: Active development
  • Feature branches: New patterns or features
  • Pull request reviews before merging

Testing Protocol

Pre-Release Checklist:

  • [ ] Theme Check plugin passes
  • [ ] Theme Unit Test import works
  • [ ] Accessibility audit (keyboard, screen reader)
  • [ ] Browser testing (Chrome, Firefox, Safari, Edge)
  • [ ] Mobile responsive testing
  • [ ] PageSpeed Insights > 90
  • [ ] Code linting (PHPCS with WordPress standards)

Key Takeaways for WordPress Developers

After six months of intensive FSE theme development, here are our biggest lessons:

1. theme.json is a Game-Changer

Centralizing all design configuration eliminates CSS maintenance nightmares. Every color, font size, and spacing value comes from a single source.

Benefit: Changing brand colors site-wide is a 2-minute edit, not a 2-hour CSS hunt.

2. Block Patterns > Custom Post Types

Instead of building custom post types for testimonials, team members, or services, use block patterns. They’re more flexible and user-friendly.

Benefit: Users can customize pattern layouts without touching code.

3. Variable Fonts are Production-Ready

Variable fonts reduce HTTP requests, improve performance, and provide infinite design flexibility.

Benefit: One 68KB file replaces 10+ individual font files.

4. FSE Themes Require Different Thinking

Stop thinking in PHP templates. Start thinking in reusable block compositions and visual editing experiences.

Mindshift: “How can I build this so a non-technical user can edit it?”

5. Accessibility Must Be Built In, Not Bolted On

Retrofitting accessibility is painful. Build with semantic HTML, keyboard navigation, and ARIA from day one.

Benefit: Pass WordPress.org review faster and serve all users equally.

6. Performance is a Feature

Clients notice when their site loads in under 1 second. FSE themes can achieve this without sacrificing design flexibility.

Competitive Advantage: Moiraine sites consistently score 95+ on PageSpeed Insights.

What’s Next for Moiraine

Our roadmap for continued development:

Planned Features

Q1 2026:

  • Additional mega menu layouts
  • WooCommerce integration patterns
  • E-commerce product showcase blocks

Q2 2026:

  • Animation controls (scroll reveals, fade-ins)
  • Advanced grid layout patterns
  • Form styling variations

Q3 2026:

  • Additional style variations
  • Dark mode toggle option
  • Extended typography presets

Community Contributions

Moiraine is open source (GPL v3). We welcome:

  • Pattern contributions
  • Style variation submissions
  • Bug reports and fixes
  • Translation contributions

GitHub: github.com/imagewize/moiraine
WordPress.org: wordpress.org/themes/moiraine

Conclusion: FSE is the Future of WordPress

Building Moiraine taught us that Full Site Editing isn’t just a new feature—it’s a fundamental shift in WordPress development philosophy.

For Developers:

  • Faster theme development
  • Less CSS to maintain
  • Standardized architecture
  • Better performance out of the box

For Clients:

  • Visual editing everywhere
  • No expensive page builder subscriptions
  • Faster websites
  • More design flexibility

For End Users:

  • Easier content editing
  • Consistent design system
  • Accessible by default
  • Future-proof platform

If you’re still building WordPress sites with Classic themes or heavy page builders, 2025 is the year to embrace FSE. The tooling is mature, the performance benefits are real, and the WordPress community is all-in on this direction.

Get Started with Moiraine

Try the Theme:

  • Download from WordPress.org Theme Directory
  • View demo at demo.imagewize.com
  • Explore pattern library and style variations

Learn More:

Need Custom WordPress Development?
We specialize in custom WordPress theme development and performance optimization for SMEs across the US and Europe. Contact us to discuss your project.

About the Author:
Jasper Frumau is a WordPress developer specializing in performance optimization, FSE theme development, and Trellis hosting for SMEs across the US and Europe. He builds fast, accessible WordPress sites at Imagewize.

WordPress Block Editor Resources

Official Documentation:

Community Resources:

Development Tools:

Leave a Reply