Workshop Kit · widget reference

Shipped

keyword-builder

Seeds 8 local-SEO keyword slots from restaurantProfile.cuisine + the city extracted from restaurantProfile.address, then lets the operator edit each row. Four formulas (cuisine+nbhd / dish+nbhd / occasion+nbhd / intent+cuisine+nbhd) appear twice each with different second words. Writes localKeywords as a newline-separated string — same shape the L12 text-input writes today, so the L14 generator + readiness checklist keep working.

Live demo

Type cuisine + neighborhood at the top, click "Refill all 8 slots from profile," then edit each row. Edits go to MuntinContext.localKeywords as a newline-separated string.

No config block needed — reads context, writes localKeywords

Current MuntinContext.localKeywords (newline-separated) Type a cuisine + neighborhood above and click "Refill"…

Contract

No data attributes beyond data-widget; no inline JSON config. The widget reads cuisine + address from MuntinContext.restaurantProfile and seeds suggestions; operator overrides for either the cuisine OR the neighborhood are typed inline at the top of the widget.

BehaviorNotes
Reads restaurantProfile.cuisine Pre-fills the cuisine input. Operator can edit inline without changing the profile.
Reads restaurantProfile.address Tries to extract a neighborhood / city via a simple comma-split heuristic. Falls back to a placeholder; operator overrides inline.
Reads localKeywords If the operator typed phrases previously, those WIN on first mount — the seed doesn't overwrite saved work.
Writes localKeywords Newline-separated string with one phrase per line, capped at 8. Same shape as the L12 text-input → existing L14 generator + L14 readiness checklist read it without changes.
Refill button Reseeds all 8 slots from the current cuisine + neighborhood values. Polite-region announcement names what happened.
Cuisine dictionary The dish-suggestion bank covers 12 cuisines (mexican, italian, japanese, chinese, thai, indian, mediterranean, american, french, korean, vietnamese, ethiopian). Unrecognized cuisines fall back to "signature dish" / "house special" placeholders.

Markup

<section class="course-widget" data-widget="keyword-builder"></section>

That's it. The cuisine + neighborhood inputs render inline; the 8 keyword slots seed automatically; edits commit to localKeywords on every input event.

Accessibility

Why seed instead of suggest-as-you-type

Autocomplete-as-you-type would feel responsive but hide the formula. The point of L12 is for the operator to internalize the four formulas so they can keep generating new phrases quarterly (per the L16 rhythm). Showing the formula name next to each row is the pedagogical move; the seed is just a starting point operators edit toward what their neighborhood actually searches.

Where it ships

The course-local-seo printable sheet reads from the same localKeywords string, so a quarterly print + walk-incognito-through-Google flow stays unchanged.

Source

/tools/_shared/workshop/keyword-builder.js — ~200 LOC. Exports { tag, contextKeys, mount, serialize } per the Workshop Kit widget contract. Dish-suggestion bank lives at the top of the file as a flat lookup table; neighborhood extraction is a simple comma-split heuristic on the address. The widget writes localKeywords as a string (not an array) to keep wire compatibility with the L12 text-input it replaces and the L14 generator that reads it.

← Back to the Workshop Kit