Skip to content

Proposal: Introduce Feature-Based Block Structure for Scalable FSE Starter #619

@sagarjadhav

Description

@sagarjadhav

Summary

This proposal introduces a feature-based block architecture inside theme-elementary to support scalable development of custom client blocks, while preserving the theme’s identity as a clean Full Site Editing (FSE) starter.

The goal is not to introduce a framework or PHP component system, but to improve internal organization so that custom blocks can grow in a structured and maintainable way across projects.


🎯 Problem Statement

theme-elementary currently organizes assets by file type:

assets/src/css
assets/src/js

This works for small themes. However, in client projects we typically:

  • Add multiple custom blocks
  • Add block-specific JS functionality
  • Add block-specific CSS
  • Sometimes introduce server-side rendering
  • Add custom integrations (e.g., WooCommerce, dynamic data)

A block with custom JS, scoped CSS, and a render callback may require touching multiple directories. As the number of blocks grows, this increases:

  • Risk of mismatched or orphaned files
  • Duplication of logic
  • Maintenance complexity
  • Contributor cognitive load

We need scalable structure without turning the starter into a framework.


🧩 Proposed Architecture (Block-First)

Introduce a feature-based block structure inside assets/src:

.
├── assets
│   ├── build
│   └── src
│       ├── blocks
│       │   ├── example-block
│       │   │   ├── block.json
│       │   │   ├── edit.js
│       │   │   ├── save.js
│       │   │   ├── editor.css (optional)
│       │   │   ├── style.css
│       │   │   └── render.php (optional)
│       │   └── another-block
│       │       ├── ...
│       │
│       ├── components
│       ├── css (global styles)
│       └── js  (global scripts)
│
├── inc
├── parts
├── patterns
├── templates
├── theme.json

🧠 Architectural Principles

1️⃣ Block-First, Not Framework-First

  • Each custom block lives in its own folder.
  • Blocks remain fully compliant with block.json.
  • No custom PHP view-layer abstraction is introduced.
  • No component rendering framework is added.

2️⃣ render.php Decision Rule

Use render.php when block output depends on server-side data such as:

  • Post meta
  • WooCommerce data
  • Dynamic queries
  • Context-dependent rendering

If the block is static and fully defined by editor attributes, use save.js.


3️⃣ Component Promotion Rule

The /components directory is reserved for shared JS utilities only.

Rule:

  • If logic is used by only one block → keep it inside that block’s folder.
  • If logic is used by two or more blocks → move it to /components.

No PHP view components are introduced in the starter.


4️⃣ Preserve FSE Compatibility

This proposal does not:

  • Modify template parts
  • Change patterns structure
  • Alter theme.json
  • Introduce external frameworks
  • Change asset registration behavior
  • Replace WordPress block philosophy

The theme remains a clean FSE starter.


🛠 Build Tooling

This architecture operates within the existing build pipeline (e.g., @wordpress/scripts).

Block assets are discovered and compiled via block.json fields such as:

  • editorScript
  • script
  • style
  • editorStyle

Nested block folders are fully supported by this mechanism.

Phase 1 does not:

  • Modify asset output paths
  • Change block registration behavior
  • Introduce new runtime dependencies

Build behavior remains unchanged.


🪜 Implementation Plan

Phase 1 — Introduce Structure

  • Add /blocks directory inside assets/src
  • Add one example block as reference
  • Ensure build parity with existing setup
  • No breaking changes

Phase 2 — Documentation

Add a block creation checklist covering:

  • Required block.json fields
  • Naming conventions
  • When to use render.php
  • When to promote shared logic to /components
  • Editor vs frontend asset separation

Phase 3 — Gradual Adoption

  • All future client-specific blocks follow this structure
  • Existing global CSS/JS may be refactored incrementally

📊 Success Criteria

  • At least one example block implemented in the new structure
  • No increase in frontend bundle size
  • No regression in Global Styles behavior
  • No change in FSE template behavior
  • Documentation updated with clear block creation guidelines

📦 Expected Outcomes

  • Clean scaling from 1 to 20+ custom blocks
  • Reduced duplication across client projects
  • Clear contributor rules that prevent architectural drift

⚠️ Non-Goals

  • Introducing a PHP component rendering framework
  • Replacing Gutenberg block system
  • Converting the starter into an enterprise theme framework
  • Breaking backward compatibility

If approved, Phase 1 will introduce the folder structure and a single example block to validate the approach before wider adoption.

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions