Skip to content
Content
Skill

/website-builder

Building Website Builder editor components, theming, and CMS integration using @webiny/website-builder-nextjs. Use this skill when the developer wants to create editor components for the Website Builder, register components with createComponent, define configurable inputs (text,

BOOST
From plugin
webiny-js
8k76 skills3 MCP
Install
$ npx -y skills add webiny/webiny-js --skill website-builder --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/website-builder

Context preview

The summary Claude sees to decide when to auto-load this skill.

Building Website Builder editor components, theming, and CMS integration using @webiny/website-builder-nextjs. Use this skill when the developer wants to create editor components for the Website Builder, register components with createComponent, define configurable inputs (text,

SKILL.md

website-builder.SKILL.md
name: webiny-website-builder
description: >
  Building Website Builder editor components, theming, and CMS integration using
  @webiny/website-builder-nextjs. Use this skill when the developer wants to create editor
  components for the Website Builder, register components with createComponent, define
  configurable inputs (text, number, boolean, color, select, file/image, slot, lexical, object,
  tags), type the component's props correctly (especially file/image inputs, which are objects
  with { src, width, height, ... } and NOT plain strings, and lexical inputs which are
  { html, state } objects), set up component groups, customize the theme (CSS variables,
  createTheme, Tailwind bridge, fonts), build Server Components that fetch CMS data, or
  understand the WB architecture (Admin iframe + Next.js). Also use for anything related to
  the Website Builder starter kit.

Website Builder

TL;DR

The Webiny Website Builder uses a unique architecture: the Admin editor loads your Next.js app inside an iframe. All component code and styles live in your Next.js project -- Webiny only stores the page structure (which components and what input values). You build editor components with `@webiny/website-builder-nextjs`, register them via `createComponent()`, define configurable inputs, and manage theming through CSS custom properties and `createTheme()`.

Architecture

+----------------------------------------------------------+
|  Webiny Admin                                            |
|  +----------------------------------------------------+  |
|  |  Website Builder Editor                            |  |
|  |                                                    |  |
|  |   sidebar     +------------------------------+     |  |
|  |   (inputs)    |  your Next.js app (iframe)   |     |  |
|  |               |  real components             |     |  |
|  |               |  real styles                 |     |  |
|  |               +------------------------------+     |  |
|  +----------------------------------------------------+  |
+----------------------------------------------------------+
                        postMessage (SDK)
+----------------------------------------------------------+
|  Your Next.js App (running separately)                   |
|  @webiny/website-builder-nextjs SDK installed            |
+----------------------------------------------------------+

Key implications:

  • **No style clashes** -- your components, your styles, full ownership
  • **Genuine WYSIWYG** -- editors see your real app, not a simulation
  • **Framework-owned code** -- all React components live in your Next.js repo

Setup

Starter Kit

git clone https://github.com/webiny/website-builder-nextjs.git my-website
cd my-website
npm install

Ensure `@webiny/website-builder-nextjs` and `@webiny/sdk` versions in `package.json` match your Webiny version (`yarn webiny --version` in your Webiny project).

Environment Variables

# .env
NEXT_PUBLIC_WEBSITE_BUILDER_API_KEY=your_wb_api_key
NEXT_PUBLIC_WEBSITE_BUILDER_API_HOST=https://your-cloudfront-url.cloudfront.net
NEXT_PUBLIC_WEBSITE_BUILDER_ADMIN_HOST=http://localhost:3001
NEXT_PUBLIC_WEBSITE_BUILDER_API_TENANT=root

Editor Components

An editor component has two parts:

1. **React component** -- renders the UI, receives configured values via `inputs` prop 2. **Manifest** -- metadata (name, label, group, inputs) that tells the editor about the component

Creating a Component

// src/editorComponents/Banner.tsx
import React from "react";
import { ComponentProps } from "@webiny/website-builder-nextjs";

interface BannerInputs {
  headline: string;
  ctaLabel: string;
  ctaUrl: string;
}

export function Banner({ inputs: { headline, ctaLabel, ctaUrl } }: ComponentProps<BannerInputs>) {
  return (
    <div className="bg-primary py-12 px-6 text-center text-white">
      <h2 className="text-3xl font-bold mb-4">{headline}</h2>
      {ctaLabel && ctaUrl && (
        <a
          href={ctaUrl}
          className="inline-block bg-white text-primary font-semibold px-6 py-3 rounded-md"
        >
          {ctaLabel}
        </a>
      )}
    </div>
  );
}

Registering Components

The `editorComponents` array must be in a `"use client"` file:

// src/editorComponents/index.tsx
"use client";
import { createComponent, createTextInput } from "@webiny/website-builder-nextjs";
import { Banner } from "./Banner";

export const editorComponents = [
  createComponent(Banner, {
    name: "Custom/Banner",
    label: "Banner",
    group: "custom",
    inputs: [
      createTextInput({
        name: "headline",
        label: "Headline",
        description: "The main headline text.",
        defaultValue: "Ready to get started?"
      }),
      createTextInput({
        name: "ctaLabel",
        label: "Button Label",
        defaultValue: "Get started"
      }),
      createTextInput({
        name: "ctaUrl",
        label: "Button URL",
        defaultValue: "/"
      })
    ]
  })
];

**Important:** The `"use client"` directive is required because component registration communicates with the editor via the browser. However, components imported here can still be Server Components if they don't have their own `"use client"` directive.

Component Name Convention

Use a namespaced string: `"YourNamespace/ComponentName"`. Component names are stored in page documents -- treat them as **stable identifiers**; renaming breaks existing pages.

Input Types

| Factory Function | Use Case | | --------------------- | ----------------------------------- | | `createTextInput` | Single-line text, URLs, labels | | `createLongTextInput` | Multi-line text | | `createNumberInput` | Numeric values | | `createBooleanInput` | Toggle / checkbox | | `createColorInput` | Color picker | | `crea

Read more
Ships withwebiny-js

Open-source content platform. Self-hosted on AWS serverless. Built as a TypeScript framework you extend with code, not a closed product you configure through a UI. Runs on Lambda, DynamoDB, S3, and CloudFront inside your own AWS account. Scales automatically.

Get the whole plugin
Stats
8,049
Stars
682
Forks
Active
Maintenance
TypeScript
Language
12h ago
Last commit
8y ago
Created
2d ago
Added

Repo: webiny/webiny-js

Other skills on webiny-js.