Shipkit
DocsFeaturesPricing
DocsFeaturesPricing

Command Palette

Search for a command to run...

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

Multi-Zone Architecture

Multi-zone lets you deploy separate Shipkit installations under one domain. Each zone is a full app customized for its purpose (docs, blog, UI library, tools) while sharing design and auth.

shipkit.io/          -> Main app (marketing, dashboard)
shipkit.io/docs/*    -> Documentation app
shipkit.io/blog/*    -> Blog app
shipkit.io/ui/*      -> Component library
shipkit.io/tools/*   -> Developer tools

Deployment Options

Next.js Multi-Zone (Recommended)

Soft navigation within zones, optimal performance. The main app uses rewrites in next.config.ts to proxy requests to zone apps.

Vercel Proxy Project

Simplest setup. A standalone Vercel project with rewrites routes traffic to each zone. Hard navigation between all routes.

Incremental Approach

Add rewrites to your existing config and deploy zones one at a time. Start with docs or blog.

Setup

1. Configure Rewrites on Main App

Add to your existing next.config.ts:

async rewrites() {
  const multiZoneRewrites = [];

  if (process.env.DOCS_DOMAIN) {
    multiZoneRewrites.push(
      { source: '/docs', destination: `${process.env.DOCS_DOMAIN}/docs` },
      { source: '/docs/:path*', destination: `${process.env.DOCS_DOMAIN}/docs/:path*` },
      { source: '/docs-static/:path*', destination: `${process.env.DOCS_DOMAIN}/docs-static/:path*` }
    );
  }

  if (process.env.BLOG_DOMAIN) {
    multiZoneRewrites.push(
      { source: '/blog', destination: `${process.env.BLOG_DOMAIN}/blog` },
      { source: '/blog/:path*', destination: `${process.env.BLOG_DOMAIN}/blog/:path*` },
      { source: '/blog-static/:path*', destination: `${process.env.BLOG_DOMAIN}/blog-static/:path*` }
    );
  }

  // Same pattern for /ui and /tools
  return multiZoneRewrites;
}

2. Create Zone Apps

Clone Shipkit for each zone:

git clone https://github.com/lacymorrow/shipkit.git shipkit-docs
cd shipkit-docs && bun install --frozen-lockfile

3. Configure Zone next.config.ts

Each zone needs basePath and assetPrefix:

const nextConfig: NextConfig = {
  basePath: "/docs", // or /blog, /ui, /tools
  assetPrefix: "/docs-static", // unique per zone

  async rewrites() {
    return {
      beforeFiles: [
        {
          source: "/docs-static/_next/:path+",
          destination: "/_next/:path+",
        },
      ],
    };
  },

  // Rest of Shipkit configuration
};

4. Environment Variables

Main app .env.local:

# Development
DOCS_DOMAIN=http://localhost:3001
BLOG_DOMAIN=http://localhost:3002
UI_DOMAIN=http://localhost:3003
TOOLS_DOMAIN=http://localhost:3004

Production (Vercel dashboard):

DOCS_DOMAIN=https://docs-shipkit.vercel.app
BLOG_DOMAIN=https://blog-shipkit.vercel.app
UI_DOMAIN=https://ui-shipkit.vercel.app
TOOLS_DOMAIN=https://tools-shipkit.vercel.app

Each zone app gets its own .env.local with zone-specific NEXT_PUBLIC_APP_URL, DATABASE_URL, etc.

Local Development

Start each app on different ports:

# Terminal 1 - Main app
bun dev

# Terminal 2 - Docs
cd ../shipkit-docs && bun dev -- --port 3001

# Terminal 3 - Blog
cd ../shipkit-blog && bun dev -- --port 3002

Test routes:

  • http://localhost:3000/ -> Main app
  • http://localhost:3000/docs -> Proxied to docs app
  • http://localhost:3000/blog -> Proxied to blog app

Cross-Zone Navigation

Use anchor tags (<a>) for links between zones (hard navigation). Use Next.js <Link> for navigation within a zone (soft navigation).

// Within a zone (soft navigation)
import Link from "next/link"
<Link href="/dashboard">Dashboard</Link>

// Between zones (hard navigation)
<a href="/docs/getting-started">Documentation</a>
<a href="/blog/latest">Blog</a>

Zone Customization

Each zone is a full Shipkit installation. Customize by:

  • Enabling/disabling features via env vars
  • Removing unnecessary routes and components
  • Adding zone-specific dependencies (e.g., Storybook for UI zone)
  • Sharing or separating databases

Considerations

  • SEO: Each zone should have proper meta tags and sitemap entries
  • Auth: Zones can share authentication if they share AUTH_SECRET and DATABASE_URL
  • Analytics: Ensure tracking works across all zones
  • Components: All zones share Shipkit's component library for consistent design
  • Bundle size: Each zone is independently optimized