Skip to content

Custom block server-render: WASM↔JS bridge via hook bus (block.render:{slug}/{handler}) #222

@tayebmokni

Description

@tayebmokni

Summary

Implement the WASM-JS bridge for plugin-supplied block server-renderers. When a block declares render: { handler }, the renderer pipeline (1) looks up the registering plugin from the blocks namespace, (2) constructs synthetic hook name block.render:{plugin_slug}/{handler}, (3) dispatches as a FILTER via the hook bus, (4) caches result by (block_type, attrs_hash, content_version).

The bridge has no separate WASM export — it is one more dispatch through the single hook_handler entry point.

Design reference

  • docs/02-plugin-system.md §7.4 (cross-refs doc 04 §2.1, doc 07 §15.5)

Acceptance criteria

  • registerBlock SDK helper constructs the canonical doc-04 BlockTypeDefinition shape (same shape as core blocks)
  • Block attribute schemas validated against JSON Schema 2020-12 (per §7.7)
  • When server-renderer pipeline encounters a block with render: { handler }:
    • Look up registering plugin from block namespace (gn-seo/meta -> gn-seo)
    • Build hook name block.render:gn-seo/seo_meta.render
    • Dispatch as filter via hook bus with HookCall{block: {name, attributes}, context: {post_id, view, locale, ...}}
  • Plugin pre-declares the hook in its manifest hooks.filters for fast-path lookup, OR registers in init() via host_register_hook
  • Renderer caches result by (block_type, attrs_hash, content_version) per doc 07 §15.5
  • Cache tags emitted via the cache.invalidate capability follow doc 07 §15 conventions
  • Block with render but no save -> dynamic (server-rendered every fetch unless cached)
  • Block with both save and render -> static HTML for public site + server-render available for preview/admin
  • Tests: server-render dispatch round-trip; cache hit on identical attrs; cache invalidation by tag

Dependencies

#73 (hook bus), #95 (hook handler), #214 (frontend SDK), doc 04 (block editor), doc 07 §15 (cache tags)

Complexity

M

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions