Shipkit
DocsFeaturesPricing
DocsFeaturesPricing

Shipkit DocumentationBuild memory optimizationDevelopment GuideEnvironment VariablesError HandlingFile StructureMiddlewareRebranding Guide

Vercel Deployment Checks

Development GuideCLIDependency UpdatesDevToolsFeature FlagsAI PromptsSetup RequirementsSupply chaintRPCWeb Workers

FeaturesAIAnalytics IntegrationAuthenticationCMSDatabaseEmailHapticsPaymentsComponent RegistryStorageUIVisual BuilderWaitlist Feature

Quick StartDeploymentEnvironment VariablesFile StructureSetup Wizard

Caching & Rate LimitingContent ManagementError HandlingMarkdown and MDXMiddlewareProxy-Safe Server ActionsRebranding GuideWebhook Security Implementation GuideMulti-Zone ArchitectureVercel Deployment

IntegrationsPayload CMSDataFast Analytics IntegrationGoogle Analytics IntegrationGoogle Tag Manager IntegrationPostHogStatSig IntegrationUmami Analytics IntegrationAuth.js IntegrationBetter AuthClerkStack Auth IntegrationSupabase Authentication IntegrationBuilder.io IntegrationPayload CMS IntegrationAWS S3 IntegrationResend Email IntegrationUpstash Redis IntegrationVercel Blob IntegrationLemon SqueezyPolarStripe

API RoutesComponentsAPI Route SnippetsAuthentication SnippetsComponent SnippetsForm Handling SnippetsSnippets Introduction

    Visual Builder

    Shipkit integrates Builder.io for drag-and-drop page building. Non-technical users can create and edit pages visually without touching code.

    Setup

    NEXT_PUBLIC_BUILDER_API_KEY=your-builder-api-key
    # Or: BUILDER_API_KEY (auto-mirrored to NEXT_PUBLIC_BUILDER_API_KEY)
    

    Disable explicitly with DISABLE_BUILDER=true.

    How It Works

    1. Register custom components in src/builder-registry.ts
    2. Create/edit pages in the Builder.io visual editor at builder.io/app
    3. Pages render at /builder.io/{slug} or through the unified catch-all route
    4. Content is fetched from Builder.io's API and rendered client-side
    5. Pages are cached with ISR (60-second revalidation)

    Registered Components

    Three components are registered for use in the visual editor:

    Hero

    Full-width hero section with title, subtitle, CTA button, and optional background image.

    Props: title, subtitle, buttonText, buttonLink, backgroundImage

    Stats

    Statistics section with configurable grid layout.

    Props: title, subtitle, stats[] (value, label, description), columns (2/3/4), background (white/gray)

    CTA (Call-to-Action)

    Section with heading, description, and up to two buttons. Supports background images.

    Props: title, description, backgroundImage, primaryButton (text, link, variant), secondaryButton

    Adding Custom Components

    Create a component in src/components/modules/builder/:

    // src/components/modules/builder/pricing.tsx
    export function Pricing({ title, plans }: PricingProps) {
      return (
        <section>
          <h2>{title}</h2>
          {/* render plans */}
        </section>
      );
    }
    

    Register it in src/builder-registry.ts:

    import { Builder } from "@builder.io/react";
    import { Pricing } from "@/components/modules/builder/pricing";
    
    Builder.registerComponent(Pricing, {
      name: "Pricing",
      inputs: [
        { name: "title", type: "string", defaultValue: "Pricing" },
        {
          name: "plans",
          type: "list",
          subFields: [
            { name: "name", type: "string" },
            { name: "price", type: "number" },
          ],
        },
      ],
    });
    

    The component will appear in the Builder.io visual editor's component panel.

    Coexistence with Payload CMS

    Shipkit checks Payload first, then Builder.io. If a page exists in Payload, it takes priority. Builder.io serves as a fallback for pages not managed in Payload.

    Both systems can coexist: use Payload for structured content (blog posts, FAQs) and Builder.io for marketing/landing pages.

    Preview Mode

    The useIsPreviewing() hook from Builder.io detects when you're editing in the visual editor. Content renders even without being published, so you get live preview during editing.

    Installing in Other Projects

    Builder.io is available as a shadcn registry block:

    npx shadcn add @shipkit/builder-io   # Standalone Builder.io integration
    npx shadcn add @shipkit/cms-pages    # Shared Payload + Builder.io catch-all
    

    See Component Registry for setup.

    Key Files

    FilePurpose
    src/builder-registry.tsComponent registration
    src/lib/builder-io/builder-io.tsxRenderer component (RenderBuilderContent)
    src/app/(app)/[...slug]/page.tsxUnified CMS catch-all (Payload + Builder.io)
    src/app/(app)/(integrations)/builder.io/[...slug]/page.tsxStandalone Builder.io route
    src/components/modules/builder/Builder-specific components (hero, cta, stats)
    src/styles/builder-io.cssStyle overrides