Website Builder > Essentials
Custom Components
Learn how to add custom components in the Next.js starter kit with Website Builder.
- how to add custom components to your Website Builder
In this tutorial, we explain how to create, register and use custom components in this Website Builder project.
- Step 1: Add a React component file
- Step 2: Register the component
- Step 3: Ensure the group matches the one registered
- Step 4: Open the editor to verify the component appears in the chosen group
Overview
- Custom components live in the
src/editorComponentsfolder and are provided to the renderer viaeditorComponentsexported fromsrc/editorComponents/index.tsx. - The page renderer (
src/components/DocumentRenderer.tsx) passeseditorComponentstoDocumentRendererfrom@webiny/website-builder-nextjs. - Component groups (used in the editor UI) are registered in
src/contentSdk/initializeContentSdk.tsusingregisterComponentGroup.
Files to Inspect
src/editorComponents/index.tsx— the central list of editor components and input definitionssrc/components/DocumentRenderer.tsx— how components are provided to the renderersrc/contentSdk/initializeContentSdk.ts— where component groups are registered
Step-by-Step: Create a New Custom Component
Step 1: Add a React Component File
Add a React component file under src/editorComponents (or a subfolder). In this tutorial we will create CalloutBox component.
- Prefer exporting a named component (e.g.
export const CalloutBox = () => { ... }). - Keep the component as a standard React functional component.
Example minimal component:
Step 2: Register the Component
Define editor inputs and register the component in src/editorComponents/index.tsx.
- Use
createComponentfrom@webiny/website-builder-nextjsto register the component withname,label,groupandinputs. - Use input helpers such as
createTextInput,createLongTextInput,createLexicalInput,createFileInput,createSelectInput,createSlotInput.
Example registration snippet (add to src/editorComponents/index.tsx):
Notes:
- The
nameproperty defines the unique editor identifier (used by the editor to save/load the block). - The
groupshould match a component group registered insrc/contentSdk/initializeContentSdk(e.g.,custom,basic).
How inputs map to component props
- When the editor renders the page, the
DocumentRendererwill render your component and pass the block data as props. - Typical convention: input names map to prop names. For example,
titlebecomesprops.titleinside your component. - For slot inputs (
createSlotInput) the renderer will pass an array of nested blocks which you should render usingchildrenor a dedicated renderer.
Step 3: Ensure the Group Matches the One Registered
- Component groups (editor categories) are registered in
src/contentSdk/initializeContentSdk.tswithregisterComponentGroup. - Pick an existing group (
basic,sample) or add a new one ininitializeContentSdk.ts.
In this tutorial, we used an existing group, but if you ned to create a new one, for example, a new Demo Group add the following to initializeContentSdk.ts:
Note: the order in which the Component groups show in the Website builder depends on the order in which they were added to the file above.
Keep components presentation-focused; prefer receiving plain data from inputs rather than coupling to editor APIs inside the component.
For rich text, prefer
createLexicalInputwhere content is saved as Lexical nodes and will be rendered byDocumentRenderer.Use
createSlotInputto allow nesting arbitrary content inside your block.Keep components SSR-friendly. Use client-only code (like browser-only libs) inside a child component or guarded by dynamic import to avoid SSR issues.
Step 4: Open the Editor to Verify the Component Appears in the Chosen Group and That It Is Functional.
- Run the site and open a new Page in the editor to verify the component appears in the chosen group.
- Drag and drop the new component in the Page to validate it is functional.
Callout Box Custom Component