You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Widget types need a single source-of-truth metadata file, just as blocks have block.json. The schema has three consumers:
@wordpress/build (to emit the widget manifest)
Core PHP (to register widget types on init)
JS (to type-check consumers).
This issue formalizes the shape of that file and publishes the JSON Schema at schemas/json/widget.json (mirrored to schemas.wp.org/trunk/widget.json).
A minimal widget.json already exists as a fixture in #77347 (widgets/hello-world/widget.json) to keep the build pipeline honest; this issue turns that implicit contract into a public, validated schema and aligns it with the broader widget-types work.
Proposed shape
Baseline with the minimum fields to register a widget type end-to-end:
{
"$schema": "https://schemas.wp.org/trunk/widget.json",
"apiVersion": 1,
"name": "core/on-this-day",
"title": "On this day",
"description": "Surface posts published on this day in previous years.",
"icon": "calendar",
"category": "dashboard",
"textdomain": "default",
"attributes": [ /* DataViews Field<>[] — see notes below */ ]
}
The attributes array contains entries shaped like Field<> from @wordpress/dataviews (packages/dataviews/src/types/field-api.ts). Each entry declares an attribute that DataForm can render as the right control automatically — so any surface that hosts the widget gets attribute editing for free, without per-widget form code. The JSON schema validates the JSON-expressible subset of that type; runtime-only properties (React components, callbacks) are augmented from the widget's JS module at registration time.
Module entry points and style assets are discovered by convention from the widget directory — the build pipeline in #77576 picks up render.*, widget.*, and render.scss automatically. The schema intentionally does not declare pointers for these in its first iteration; the shape above is exactly what the build honors today. Overrides for non-convention cases can be added in a follow-up if real-world use cases emerge.
Divergences from block.json
Where widget.json mirrors block.json 1:1, no explanation is needed. The table below captures only what changes and why — it's the part of the schema worth debating.
block.json
widget.json
Reason
save
—
Widgets render dynamically; no serialized save function.
parent / ancestor / allowedBlocks
—
Widgets are not nested in a block tree.
providesContext / usesContext
—
Block-tree context is not applicable.
supports
—
Block supports API is block-specific; widget-specific supports can land as a follow-up.
editorScript
—
Widgets are not edited in a block editor; there is no equivalent authoring script.
render, script, style, viewScript
—
Module entry points and styles are discovered by convention from the widget directory (render.*, widget.*, render.scss).
attributes (block-style)
attributes (DataViews Field<>)
Declarative schema so any surface that hosts the widget can render attribute editing through DataForm without per-widget form code.
Tasks
Publish JSON Schema at schemas/json/widget.json
Add integration tests under test/integration/ covering schema validation
TypeScript types (WidgetType, WidgetTypeMetadata) exported from @wordpress/widget-types
Validate the existing widgets/hello-world/widget.json fixture against the new schema
Document the shape in the schema README, including the divergences table above
Scope
The following are explicitly out of scope for this issue and land in separate follow-ups:
The PHP register_widget_type() API and manifest reader
The Field[] attribute editor / rendering contract
Optional overrides for module entry points and style assets (renderModule, widgetModule, style, editorStyle) — to be added once real-world cases require them
Additional render types beyond developer-defined modules (for example, block compositions or saved entities) — the schema is designed to extend non-breakingly in that direction
Promotion from __experimental once the shape is stable
Part of the Dashboard Overview #77616.
Widget types need a single source-of-truth metadata file, just as blocks have
block.json. The schema has three consumers:@wordpress/build(to emit the widget manifest)init)This issue formalizes the shape of that file and publishes the JSON Schema at
schemas/json/widget.json(mirrored toschemas.wp.org/trunk/widget.json).A minimal
widget.jsonalready exists as a fixture in #77347 (widgets/hello-world/widget.json) to keep the build pipeline honest; this issue turns that implicit contract into a public, validated schema and aligns it with the broader widget-types work.Proposed shape
Baseline with the minimum fields to register a widget type end-to-end:
{ "$schema": "https://schemas.wp.org/trunk/widget.json", "apiVersion": 1, "name": "core/on-this-day", "title": "On this day", "description": "Surface posts published on this day in previous years.", "icon": "calendar", "category": "dashboard", "textdomain": "default", "attributes": [ /* DataViews Field<>[] — see notes below */ ] }The
attributesarray contains entries shaped likeField<>from@wordpress/dataviews(packages/dataviews/src/types/field-api.ts). Each entry declares an attribute thatDataFormcan render as the right control automatically — so any surface that hosts the widget gets attribute editing for free, without per-widget form code. The JSON schema validates the JSON-expressible subset of that type; runtime-only properties (React components, callbacks) are augmented from the widget's JS module at registration time.Module entry points and style assets are discovered by convention from the widget directory — the build pipeline in #77576 picks up
render.*,widget.*, andrender.scssautomatically. The schema intentionally does not declare pointers for these in its first iteration; the shape above is exactly what the build honors today. Overrides for non-convention cases can be added in a follow-up if real-world use cases emerge.Divergences from
block.jsonWhere
widget.jsonmirrorsblock.json1:1, no explanation is needed. The table below captures only what changes and why — it's the part of the schema worth debating.block.jsonwidget.jsonsaveparent/ancestor/allowedBlocksprovidesContext/usesContextsupportseditorScriptrender,script,style,viewScriptrender.*,widget.*,render.scss).attributes(block-style)attributes(DataViewsField<>)DataFormwithout per-widget form code.Tasks
schemas/json/widget.jsontest/integration/covering schema validationWidgetType,WidgetTypeMetadata) exported from@wordpress/widget-typeswidgets/hello-world/widget.jsonfixture against the new schemaScope
The following are explicitly out of scope for this issue and land in separate follow-ups:
@wordpress/build(wp-build: Add automatic widget discovery and registration #77576)register_widget_type()API and manifest readerField[]attribute editor / rendering contractrenderModule,widgetModule,style,editorStyle) — to be added once real-world cases require them__experimentalonce the shape is stableRelated