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.
fieldstakes any Puck field type:text,textarea,number,select,radio,array,custom.- Spread
...colorOverrideFields()and...visibilityFields()from@olgax.com/sdkintofieldsfor per-block colors and new/returning-visitor rules. See Theming and Personalization. - Style with the
--olgax-*CSS variables so the block follows the site theme. - Avoid hooks unless the file starts with
"use client": blocks render in the editor and on the server. - Give new fields a value in
defaultPropsand make the view handle missing values. Pages you already saved don't have the new field until someone edits and saves them again.
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.