component-scaffold
Paste into Claude Code, Claude.ai, the desktop app, or the browser extension — ⌘/Ctrl+V. ✓ Copied. Switch to Claude and paste — ⌘/Ctrl+V.
Component Scaffold
Scaffold a single production-ready front-end component with typed props, accessible markup, a Storybook story, and a test stub — wired to the CMS data shape that the project actually uses. Run this once per component, not once per project.
Usage
/component-scaffold <ComponentName> [options]
Options
| Flag | Description | Default |
|---|---|---|
--adapter |
react | jss | sxa | umbraco |
auto-detect |
--datasource |
Sitecore template / Umbraco document type alias | inferred from ComponentName |
--fields |
Comma-separated name:type pairs |
interactive discovery |
--variant |
Named JSS/SXA rendering variant slug | Default |
--test |
vitest | jest |
detect from package.json |
--path |
Output directory override | convention-detected |
Quick examples
/component-scaffold HeroBanner --adapter jss --fields "heading:Text,body:RichText,cta:Link,image:Image"
/component-scaffold PromoCard --adapter sxa --fields "headline:Text,image:Image" --variant Landscape
/component-scaffold TestimonialBlock --adapter umbraco --datasource TestimonialContent --fields "quote:string,author:string,role:string"
/component-scaffold FilterBar --adapter react --fields "label:string,options:string[]"
Phase 1 — Detect project conventions
Before writing a single file, read the project:
- Identify the adapter if not specified:
- Glob for
package.jsonand check dependencies:@sitecore-jss/sitecore-jss-nextjs→jss; asxadirectory undersrc/components/→sxa;@umbraco-cmsorumbracoDeliveryApiBaseUrl→umbraco; otherwise →react.
- Glob for
- Locate the component root: check common paths in order —
src/components/,src/components/<ComponentName>/,components/,src/rendering/. - Locate existing component peers using Glob to find
*.tsxfiles and read one as a style reference (named exports vs default, import order, CSS module vs Tailwind vs styled,clsx/cxhelper usage). - Locate the Storybook config (
*.stories.tsxfiles,.storybook/main.ts). Note whether stories use CSF 3 (Meta + StoryObj) or CSF 2. - Locate the test runner config (
vitest.config.ts,jest.config.ts,*.test.tsxpeers). Note the import style (Testing Library, Storybook play-fn, Playwright CT). - For JSS: read
src/temp/componentFactory.tsorsrc/components/index.tsto understand whether the project uses manual registration or auto-discovery. - For SXA: check for a
src/rendering/layout service variant map. - For Umbraco: locate the Block Dispatcher (
BlockDispatcher.tsx,blockMap.ts) if present.
Report what you found in a brief "Convention snapshot" before proceeding.
Phase 2 — Resolve the component shape
If --fields is supplied, parse it into a typed field map (see reference.md#field-types).
If not supplied, either:
- Read an existing Sitecore manifest / JSON route file for the template, or
- Read the Umbraco document type from
umbraco-types.tsor an Orval-generated model file, or - Ask the user to list the fields before continuing.
For each field, resolve the import and prop type using the adapter rules in reference.md.
Phase 3 — Write the component file
Create <path>/<ComponentName>/index.tsx (or the convention-matched path).
Use the correct template from templates.md:
- React (plain) —
templates.md#react-plain - JSS Next.js —
templates.md#jss-nextjs - SXA rendering variant —
templates.md#sxa-variant - Umbraco headless block —
templates.md#umbraco-block
Apply these invariants regardless of adapter:
- Named export matching the component name. No default export (tree-shaking).
- Props interface declared as
<ComponentName>Props, exported. - Destructure props at the top of the render function — no
props.xchains in JSX. - Accessible markup: at minimum, a semantic container element,
roleif non-semantic,aria-labelon interactive elements,alton every image field. - Class names: honour the detected CSS strategy (module, Tailwind, BEM). Never inline styles.
- No hardcoded strings in JSX — field-driven text uses the field helper; static UI copy uses
an
ariaLabelsconst block at the top of the file so it can be extracted for i18n.
Phase 4 — Write the Storybook story
Create <path>/<ComponentName>/<ComponentName>.stories.tsx.
Use the correct story template from templates.md:
- CSF 3 with
MetaandStoryObjgenerics (current Storybook 8 standard). - Default story named
Default; add a story per meaningful state variation (e.g.WithoutImage,LongHeadline,RTL). - Mock data shaped like real CMS output — use the mock factories from
reference.md#mock-data. - For JSS stories: stub
useSitecoreContextviaparameters.nextjsor a decorator. - For Umbraco stories: provide a plain object matching the delivery API shape.
Phase 5 — Write the test stub
Create <path>/<ComponentName>/<ComponentName>.test.tsx.
Use the correct test template from templates.md:
- Import
renderandscreenfrom@testing-library/react. - Write three baseline tests:
- Renders without crashing — render with minimal props, assert the container exists.
- Renders expected text — assert a key text field appears in the DOM.
- Accessibility —
expect(container).toHaveNoViolations()(requiresjest-axeorvitest-axe; note the dependency if not present).
- Leave a clearly marked
// TODO: add interaction testsblock for play-fn or userEvent tests.
Phase 6 — Register (adapter-specific)
After writing the files, tell the engineer exactly what manual registration step (if any) is needed:
- JSS auto-discovery: no action needed — the component name is picked up by the factory.
- JSS manual registry: add an entry to
src/temp/componentFactory.ts:components.set('<ComponentName>', dynamic(() => import('../components/<ComponentName>'))); - SXA: add the variant to the rendering variant map in
src/rendering/VariantMap.ts. - Umbraco Block Dispatcher: add a line to
blockMap.ts:'<datasource-alias>': ComponentName, - React (plain): no framework registration required — re-export from the barrel if one exists.
Phase 7 — Post-scaffold checklist
Print a concise checklist the engineer must complete manually:
- Fill in the field types that were left as
// TODOplaceholders (if any fields were ambiguous from discovery). - Add the component to the appropriate barrel / index file if the project uses one.
- Verify the Storybook story renders correctly (
npm run storybook). - Run tests to confirm the stub passes (
npm testornpx vitest). - Add the rendering item / block type in the CMS (Sitecore Content Editor / Umbraco backoffice) and assign the datasource template.
- Run the accessibility check locally (
npm run a11yor equivalent). - Review props with a designer against the design token set.
Hard rules
- Never write inline
style={{}}attributes. Use the project's CSS strategy. - Never use
anyin the props interface — use the specific field type or aTODOplaceholder with an explanatory comment. - Never suppress accessibility attributes (
alt=""is only valid when the image is decorative — document that decision inline). - Never produce a file >300 lines. Split sub-components into sibling files in the same folder.
- Never touch files outside the component folder except to report what registration step is
needed — never auto-edit
componentFactory.tsorblockMap.ts.
Reference files
reference.md— field-type mapping tables (JSS, Umbraco), adapter import cheat sheet, mock data factory patterns, WCAG-required ARIA patterns by element type.templates.md— complete file templates for each adapter (react-plain, jss-nextjs, sxa-variant, umbraco-block) plus Storybook and test stubs.examples.md— worked end-to-end examples: HeroBanner (JSS), PromoCard (SXA), TestimonialBlock (Umbraco), FilterBar (plain React).
Technical details
- Source
- Standalone skill
- Author
- Dakota Smith
- Skill name
component-scaffold- Maturity
- experimental
- Security review
- No security review
- Argument hint
<ComponentName> [--adapter react|jss|sxa|umbraco] [--datasource <TemplateName>] [--fields <field1:type,field2:type>] [--variant <VariantName>] [--test vitest|jest] [--path <src/components/...>]- Allowed tools
-
ReadWriteEditGlobGrep
- File
skills/component-scaffold/SKILL.md
To use this skill in Claude Code, copy SKILL.md into your local .claude/skills/component-scaffold/ directory.
Standalone skills are not exposed via claude plugin install — that path is reserved for plugin bundles.
Edit this skill on GitHub — opens GitHub's web editor. No git knowledge needed.