chaipro
v0.1.14
Published
ChaiBuilder Pro - AI Enabled Website Builder for Next.js
Readme
ChaiBuilder Pro
AI-enabled visual website builder for Next.js.
Build, edit, and render websites with a block-based editor, custom React blocks, server-side data providers, and first-class App Router support.
- Site: chaibuilder.com
- Package:
chaipro - Requires: Next.js ≥ 15.3 · React ≥ 19 · Tailwind CSS 3 or 4
Why ChaiBuilder Pro
| Capability | What you get |
| ------------- | ----------------------------------------------------------------------- |
| Visual editor | Drag-and-drop canvas with Tailwind styling, media, SEO, and AI assist |
| Custom blocks | Register React components with typed props schemas (chaipro/registry) |
| Server config | Request-scoped getChaiBuilder, actions, collections, page types |
| RSC rendering | RenderChaiBlocks, ChaiPageCSS, JSON-LD, draft preview |
| Extensibility | Slots, sidebar panels, hooks, feature flags, libraries |
| Databases | Postgres, LibSQL, D1, better-sqlite3, node-pg adapters |
Install
pnpm add chaipro
# or
npm install chaiproPeer dependencies (install what you use):
pnpm add next react react-dom tailwindcss drizzle-orm
# Tailwind v4 hosts also need the PostCSS plugin:
pnpm add -D @tailwindcss/postcss
# Database example (Postgres):
pnpm add postgresQuick start
1. Wrap Next.js config
// next.config.ts
import { withChaiBuilder } from "chaipro/nextjs";
import type { NextConfig } from "next";
const nextConfig: NextConfig = {};
export default withChaiBuilder(nextConfig);2. Build server config
Plain data — keep framework imports out so scripts, CI, and the Payload CLI can import it.
// chaibuilder.config.ts
import "server-only";
import { buildChaiBuilderConfig } from "chaipro/nextjs/server";
import { createPostgresDB } from "chaipro/db/postgres"; // or chaipro/db/libsql, chaipro/db/d1, …
export const chaiConfig = buildChaiBuilderConfig({
db: createPostgresDB(process.env.DATABASE_URL!),
globalDataProvider: async ({ lang, draft }) => ({
siteName: "My Site",
}),
});3. Server handle
The handle binds the config to a request context — who is asking, for which site, in what mode — and returns the getChaiBuilder every entry point imports.
On Payload, the resolver is already written:
// chaibuilder.server.ts
import { createPayloadChaiBuilder } from "chaipro/payload";
import { chaiConfig } from "@/chaibuilder.config";
export const { getChaiBuilder } = createPayloadChaiBuilder(chaiConfig);Identity, tenant, draft state, and site URL all come from Payload. What a user may do comes from their app_users membership, with their role expanded into concrete permissions — a Payload login on its own grants no builder access. Override per field as needed:
createPayloadChaiBuilder(chaiConfig, {
appId: ({ request }) => tenantFromHost(request), // multi-tenant
permissions: ({ userId }) => rolesFromYourOwnTable(userId), // authorize it yourself
});Anywhere else, write the resolver yourself with createChaiBuilder:
// chaibuilder.server.ts
import { cookies, draftMode } from "next/headers";
import { createChaiBuilder } from "chaipro/server";
import { chaiConfig } from "@/chaibuilder.config";
export const { getChaiBuilder } = createChaiBuilder(chaiConfig, {
context: async ({ request }) => {
const { isEnabled } = await draftMode();
// Resolve userId from the Authorization header (route handlers)
// or from cookies (pages / server actions)
return {
appId: process.env.CHAIBUILDER_APP_KEY ?? "",
siteUrl: process.env.SITE_URL,
draft: isEnabled,
userId: null,
// What they may do is decided here too. `resolveChaiAppUserAccess({ appId, userId })`
// gives ChaiBuilder's own answer from the app_users table; or supply `role` +
// `permissions` from wherever the host models access. No permissions = no access.
};
},
});4. API route (required)
// app/(builder)/api/chai/route.ts
import { getChaiBuilder } from "@/chaibuilder.server";
import { NextRequest } from "next/server";
export async function POST(request: NextRequest, props) {
const cb = await getChaiBuilder(props, request);
return cb.handleHttpAction(await request.json());
}5. Render a page
// app/(public)/[[...slug]]/page.tsx
import { getChaiBuilder } from "@/chaibuilder.server";
import { RenderChaiBlocks, ChaiPageCSS, PreviewBanner } from "chaipro/render";
type Props = { params: Promise<{ slug?: string[] }> };
export default async function Page(props: Props) {
const params = await props.params;
const slug = "/" + (params.slug?.join("/") ?? "");
const cb = await getChaiBuilder(props);
const payload = await cb.getPagePayload(slug);
if (!payload) return <div>Page not found</div>;
const { page, pageData, settings } = payload;
return (
<>
<ChaiPageCSS page={page} />
<RenderChaiBlocks page={page} pageData={pageData} settings={settings} pageProps={{ slug }} />
<PreviewBanner show={page.draft ?? false} />
</>
);
}
export async function generateMetadata(props: Props) {
const params = await props.params;
const slug = "/" + (params.slug?.join("/") ?? "");
const cb = await getChaiBuilder(props);
return cb.generateMetaData(slug);
}6. Mount the editor
// app/(builder)/editor/page.tsx
"use client";
import "../chai-setup"; // registrations before mount
import { ChaiWebsiteBuilder } from "chaipro";
export default function EditorPage() {
return <ChaiWebsiteBuilder />;
}Package entry points
| Import | Use for |
| ------------------ | -------------------------------------------------------------------- |
| chaipro | Editor UI — ChaiWebsiteBuilder, slots, hooks, panels (client-only) |
| chaipro/registry | registerChaiBlock, props helpers |
| chaipro/types | Shared TypeScript types |
| chaipro/next | withChaiBuilder for next.config |
| chaipro/server | Config, context, actions, getChaiBuilder (server-only) |
| chaipro/render | RenderChaiBlocks, ChaiPageCSS, styles helpers |
| chaipro/styles | Builder CSS |
| chaipro/db/* | Database adapters |
Never import chaipro (the editor entry) from Server Components — it throws. Use /server and /render on the server.
Custom blocks
import { registerChaiBlock, registerChaiBlockProps, stylesProp } from "chaipro/registry";
import type { ChaiBlockComponentProps, ChaiStyles } from "chaipro/types";
type AlertProps = {
message: string;
styles: ChaiStyles;
};
const Alert = ({ blockProps, styles, message }: ChaiBlockComponentProps<AlertProps>) => (
<div {...blockProps} {...styles}>
{message}
</div>
);
registerChaiBlock(Alert, {
type: "Alert",
label: "Alert",
group: "basic",
props: registerChaiBlockProps({
properties: {
styles: stylesProp("rounded-md p-4 bg-blue-50"),
message: { type: "string", title: "Message", default: "Hello" },
},
}),
i18nProps: ["message"],
aiProps: ["message"],
});Rules of thumb:
- Spread
blockPropsandstyleson the root element — never...props - Use
wrapper: true+{children}for containers - Attach
dataProviderfor async block data; handle$loading
Extend the builder UI
Register at module level in a setup file imported once before the editor mounts:
// chai-setup.ts
import {
registerChaiSlot,
registerChaiHook,
registerChaiSidebarPanel,
CHAI_SLOT_IDS,
CHAI_HOOKS,
} from "chaipro";
registerChaiSlot(CHAI_SLOT_IDS.TOPBAR_RIGHT, MyButton);
registerChaiHook(CHAI_HOOKS.BEFORE_SAVE_PAGE, async (pageData) => ({
...pageData,
updatedAt: Date.now(),
}));
registerChaiSidebarPanel("analytics", {
position: "bottom",
view: "drawer",
label: "Analytics",
button: ({ show }) => <button onClick={show}>Stats</button>,
panel: AnalyticsPanel,
});Also available: feature flags, add-block tabs, custom libraries, RJSF widgets/fields, save-to-library dialog, pre-import HTML hook.
Database adapters
import { createPostgresDB } from "chaipro/db/postgres";
import { createLibsqlDB } from "chaipro/db/libsql";
import { createD1DB } from "chaipro/db/d1";
import { createBetterSqliteDB } from "chaipro/db/better-sqlite3";
import { createNodePgDB } from "chaipro/db/node-pg";Pass the returned setup into buildChaiBuilderConfig({ db }).
Developing this repo
This repository builds and publishes the chaipro package.
pnpm install
pnpm dev # watch build (tsup)
pnpm build # production build
pnpm test # unit tests
pnpm test:integration
pnpm lint
pnpm formatAgent-oriented extension docs live in .agents/skills/chaibuilder/.
License
Limited commercial license. See chaibuilder.com for terms.
Links
- chaibuilder.com
- GitHub
- Extension patterns for AI agents:
.agents/skills/chaibuilder/SKILL.md
