# Seekmodo Gutenberg blocks

Sprint 11 PR 1 — four Gutenberg blocks under the `seekmodo/*`
namespace that wrap the Seekmodo web components:

| Block | Tag rendered | Source |
| --- | --- | --- |
| `seekmodo/search` | `<seekmodo-search-box>` | `src/search/` |
| `seekmodo/recommend` | `<seekmodo-recommendations>` | `src/recommend/` |
| `seekmodo/chat` | `<seekmodo-chat>` | `src/chat/` |
| `seekmodo/quiz` | `<seekmodo-quiz>` | `src/quiz/` |

## Architecture

These are **dynamic blocks**. The editor preview is a small static
React tree built in each `index.js`; the front-end output is
produced by the PHP render callback in
`Numinix\SeekmodoWordPress\Blocks\Registry`, which delegates to
`Numinix\SeekmodoWordPress\Blocks\AttributeSchema::render()`.

`AttributeSchema` is the **single source of truth** for the
attribute surface across the three page-builder PRs (Gutenberg in
PR 1, Elementor in PR 2, WPBakery in PR 3). When the SDK adds a new
attribute, update `AttributeSchema::attributesFor()` once and all
three builders pick it up.

## Build

```sh
npm install
npm run build      # production
npm start          # watch mode
```

The PHP registry prefers `blocks/build/<element>/block.json` when
present (output of `npm run build`) but falls back to
`blocks/src/<element>/block.json` directly. This means the editor
sources work out-of-the-box in development without a build step;
release tarballs ship the `build/` tree.

The editor JS in `src/<element>/index.js` is intentionally written
in vanilla `wp.element.createElement` (no JSX, no imports) so it
runs unmodified in the WordPress block editor without a bundler.
The `wp-scripts` build chain is set up for future iterations that
might want JSX, ESM imports, or shared editor utilities, but is
not required for the current shape.

## SDK loading

The PHP registry conditionally enqueues the locally vendored
`@seekmodo/web-components` ESM at
`assets/web-components/index.js` on any front-end page that contains
at least one Seekmodo block. Pages without a Seekmodo block pay
zero bytes of JavaScript. Operators can override the URL via the
`seekmodo_web_components_src` filter (e.g. to point at a CDN). See
`assets/web-components/README.md` for the pin/refresh ritual.
