@workspace/form-renderer package. Each layout is a self-contained directory with two files — a manifest and a shell component — plus a single line in the registry.
File structure
Step 1 — Create the manifest
manifest.ts declares the layout’s identity, its SVG thumbnail (shown in the Design panel picker), and the config fields it accepts.
LayoutManifest reference
LayoutConfigField reference
Step 2 — Create the shell component
layout.tsx is a React component that receives LayoutShellProps and renders the page structure. It is responsible for placing slots.formCard wherever the form card should appear.
LayoutShellProps reference
Always read
config values defensively with fallbacks. If a respondent has an old theme saved without your new config keys, those keys will be missing.Step 3 — Using the runner (advanced)
Therunner prop is only available in the live landing app — not in the studio canvas. It gives you access to the current question node and the respondent’s traversal state. The Split layout uses this to show the current question title in its sidebar.
runner is undefined (studio preview), the sidebar simply renders without question content. This is the expected behaviour — guard all runner access with optional chaining.
Step 4 — Register the layout
Add a single import and one entry toregistry.ts:
- The Design panel thumbnail picker (both apps)
- The
getAllLayouts()export (for any custom UI that lists layouts) - The
resolveLayout("my-layout")lookup (used at render time)
Mobile considerations
The studio canvas renders your layout at full width. On mobile the layout is shown inside a scaled device frame. A few conventions to follow:- Use
md:Tailwind breakpoints for desktop-only elements (as the Split layout’s sidebar does) - Provide a fallback mobile treatment — a slim fixed header is a good pattern
- Avoid fixed widths in
pxon the outermost wrapper; use%orvwso device-frame scaling works correctly
Complete example
The built-in Split layout is a good reference for a more complex layout using the runner:Next steps
Layouts overview
See the three built-in layouts and their config options.
Content-type plugins
Build custom question types with their own rendering logic.