Custom components in your site

A site scaffolded with create-olgax-site has a components/blocks/ folder for your own page-builder blocks. Each block is a Puck component config, and components/blocks/index.ts is the list of blocks your site uses. (To contribute to the default library itself instead, see Adding a component.)

1. Generate a block

pnpm new:component PromoBanner

This creates components/blocks/PromoBanner.tsx and PromoBanner.css and adds the block to the blocks list in components/blocks/index.ts. With pnpm dev running, it appears in the editor's component list immediately, with no restart or reload. A finished example lives in components/blocks/Callout.tsx.

2. Edit it

import type { ComponentConfig } from "@puckeditor/core";

export type PromoBannerProps = { title: string };

const PromoBannerView = ({ title }: PromoBannerProps) => (
  <section className="site-promo-banner">
    <h2>{title}</h2>
  </section>
);

export const promoBannerBlock: ComponentConfig<{ props: PromoBannerProps }> = {
  fields: { title: { type: "text" } },    // inputs editors fill in
  defaultProps: { title: "PromoBanner" }, // values when first added to a page
  render: (props) => <PromoBannerView {...props} />,
};

Save the file and the open editor updates its fields live.

3. Use it on a page

Open a page's editor (for example /home/edit) and drag the block in from the component list. Publish the page to see it live.

Adding a block by hand

Create the file and export a config like above, then add two lines to components/blocks/index.ts: an import and an entry in the blocks object, for example PromoBanner: block(promoBannerBlock). The key is the name shown in the editor and stored in each page, so renaming it affects pages that already use the block.

How it fits together

lib/puck.config.tsx merges the default components with your blocks into one config. The same config is used by the editor and by the public page renderer. Third-party component packages can still add themselves with registerComponent() from @olgax.com/sdk; see the SDK reference.