Skip to content
Content
Skill

/ui-extensions

Customizing the Webiny Admin UI -- white-labeling, custom data list columns, page-type forms, named dialogs, named drawers, and Lexical editor plugins. Use this skill when the developer wants to change branding (logo, title, theme colors), add custom columns to content entry

BOOST
From plugin
webiny-js
8k76 skills3 MCP
Install
$ npx -y skills add webiny/webiny-js --skill ui-extensions --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/ui-extensions

Context preview

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

Customizing the Webiny Admin UI -- white-labeling, custom data list columns, page-type forms, named dialogs, named drawers, and Lexical editor plugins. Use this skill when the developer wants to change branding (logo, title, theme colors), add custom columns to content entry

SKILL.md

ui-extensions.SKILL.md
name: webiny-admin-ui-extensions
description: >
  Customizing the Webiny Admin UI -- white-labeling, custom data list columns, page-type forms,
  named dialogs, named drawers, and Lexical editor plugins. Use this skill when the developer
  wants to change branding (logo, title, theme colors), add custom columns to content entry
  list views, create custom forms for Website Builder page types, register named dialogs or
  drawers that can be opened from anywhere with params, or extend the Lexical rich text editor.
  Covers AdminConfig, ContentEntryListConfig, useDialog, useDrawer, useOpenDialog, useOpenDrawer.

Admin UI Extensions

TL;DR

Admin extensions customize the Webiny Admin application. There are three main categories: **white-labeling** (logos, titles, theme colors), **custom data list columns** (adding columns to content entry tables), and **custom page-type forms** (custom form fields for Website Builder page types). All are React components registered via `<Admin.Extension>` in `webiny.config.tsx`.

**YOU MUST include the full file path with the `.tsx` extension in every `src` prop.** For example, use `src={"/extensions/MyAdminExtension.tsx"}`, NOT `src={"/extensions/MyAdminExtension"}`. Omitting the file extension will cause a build failure.

White-Labeling

Theme Colors

// extensions/AdminBranding/AdminTheme.tsx
import React from "react";
import { AdminConfig } from "webiny/admin/configs";

const { Theme } = AdminConfig;

const AdminTheme = () => {
  return (
    <AdminConfig.Public>
      <Theme.Color palette={"primary"} color={"purple"} />
      <Theme.Color palette={"secondary"} color={"green"} />
    </AdminConfig.Public>
  );
};

export default AdminTheme;
  • `palette` -- `"primary"`, `"secondary"`, `"neutral"`, etc.
  • `color` -- any CSS color value: named colors, hex (`"#6B46C1"`), or RGB.

Logo and Title

// extensions/AdminBranding/AdminTitleLogo.tsx
import React from "react";
import { AdminConfig } from "webiny/admin/configs";
import squareLogo from "./logo.png";
import horizontalLogo from "./logo.png";

const { Title, Logo } = AdminConfig;

const AdminTitleLogo = () => {
  return (
    <AdminConfig.Public>
      <Title value={"ACME Corp"} />
      <Logo
        squareLogo={<img src={squareLogo} alt={"ACME Corp"} />}
        horizontalLogo={<img src={horizontalLogo} alt={"ACME Corp"} />}
      />
    </AdminConfig.Public>
  );
};

export default AdminTitleLogo;

Register both:

<Admin.Extension src={"/extensions/AdminBranding/AdminTheme.tsx"} />
<Admin.Extension src={"/extensions/AdminBranding/AdminTitleLogo.tsx"} />

Available AdminConfig Components

| Component | Purpose | | ------------------------------------------------ | ------------------------------- | | `<Theme.Color palette="..." color="..." />` | Set theme color palette | | `<Title value="..." />` | Set the Admin app title | | `<Logo squareLogo={...} horizontalLogo={...} />` | Set square and horizontal logos |

All must be wrapped in `<AdminConfig.Public>`.

Custom Data List Columns

Add custom columns to the content entry list view in the Admin UI. Columns can be restricted to specific content models.

Full Example: Email Columns for Contact Submissions

// extensions/contactSubmission/EmailEntryListColumn.tsx
import React from "react";
import { ContentEntryListConfig } from "webiny/admin/cms/entry/list";

const { Browser } = ContentEntryListConfig;

// Custom cell component for the Email Type column
interface ContactSubmissionTableRow {
  values: {
    emailType: "work" | "personal";
  };
}

export const EmailTypeCell = () => {
  const { useTableRow, isFolderRow } = ContentEntryListConfig.Browser.Table.Column;
  const { row } = useTableRow<ContactSubmissionTableRow>();

  if (isFolderRow(row)) {
    return <>{"-"}</>;
  }

  const emailType = row.data.values.emailType;
  return emailType === "work" ? <>{"Business"}</> : <>{"Personal"}</>;
};

// Main extension component
const EmailEntryListColumn = () => {
  return (
    <ContentEntryListConfig>
      {/* Simple column using path (no custom cell needed) */}
      <Browser.Table.Column
        name={"email"}
        after={"name"}
        path={"values.email"}
        header={"Email"}
        modelIds={["contactSubmission"]}
      />
      {/* Custom cell column */}
      <Browser.Table.Column
        name={"emailType"}
        after={"email"}
        header={"Email Type"}
        modelIds={["contactSubmission"]}
        cell={<EmailTypeCell />}
      />
    </ContentEntryListConfig>
  );
};

export default EmailEntryListColumn;

Register:

<Admin.Extension src={"/extensions/contactSubmission/EmailEntryListColumn.tsx"} />

Column Props Reference

| Prop | Type | Description | | ---------- | -------------- | ------------------------------------------------------------------------- | | `name` | `string` | Unique column identifier | | `header` | `string` | Column header text | | `path` | `string` | Dot-path to the data field (e.g., `"values.email"`) -- for simple columns | | `cell` | `ReactElement` | Custom React component for complex rendering | | `modelIds` | `string[]` | Restrict column to specific content models | | `after` | `string` | Position this column after another column by name |

Custom Cell Hooks

Inside a custom `cell` component:

  • `useTableRow<T>()` -- access the full row data, typed with your interface
  • `isFolderRow(row)` -- check if the current row is a folder (return placeholder content)

Custom Page-Type Forms

Create custom

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,048
Stars
682
Forks
Active
Maintenance
TypeScript
Language
2h ago
Last commit
8y ago
Created
9h ago
Added

Repo: webiny/webiny-js

Other skills on webiny-js.