
This production ready boilerplate accumulating the experience and best practices collected at Focus Reactive. The project serves the idea of making Headless CMS-based development accessible, comfortable, and fast.
Production website
Editing experience
cd <project folder>
pnpm install
Execute following command to pull ENV variables from Vercel and replace some of the with local development values
pnpm vercel link &&pnpm vercel env pull &&mv .env.local apps/sanity/
cd apps/sanity && pnpm import-dataset
pnpm dev
Create a new repository using this template by clicking the "Use this template" button at the top of the repository page.
Await the initial workflow to be finished
Clone your new repository:
git clone <your-repository-url>
Navigate to the project directory:
cd <repository-name>
Install dependencies using pnpm:
pnpm install
Navigate to the Storyblok CLI directory:
cd apps/storyblok/CLI
Run the setup script,
⚠️ command should be executed from apps/storyblok/CLI (previous step), to consume correct environment variables:
node sb.mjs
Follow the interactive prompts in the CLI tool to:
Go to project settings in Vercel dashboard
This process ensures that global component updates are displayed on all pages.
🏁 Your CMS-based project is ready 🏁
Payload CMS with PostgreSQL, multi-tenancy, i18n, and A/B testing.
Prerequisites:
Setup:
cd apps/payloaddocker-compose up -d
cp apps/payload/.env.local.example apps/payload/.env.local
Required env vars:
DATABASE_URI="postgresql://postgres:password@localhost:5432/payload"PAYLOAD_SECRET="your-secret-key"NEXT_PUBLIC_SERVER_URL="http://localhost:3000"# Auth0 (optional, for admin auth):AUTH0_SECRET="..."AUTH0_BASE_URL="http://localhost:3000"AUTH0_ISSUER_BASE_URL="https://your-tenant.auth0.com"AUTH0_CLIENT_ID="..."AUTH0_CLIENT_SECRET="..."
pnpm --filter payload payload migratepnpm --filter payload generate:typespnpm --filter payload generate:importmap
pnpm --filter payload dev# or from monorepo root:turbo dev --filter=payload
Admin panel: http://localhost:3000/admin
Migrations:
pnpm --filter payload payload migrate:create # create new migrationpnpm --filter payload payload migrate # run pending migrations
apps/payload: CMS app (Payload CMS + PostgreSQL)apps/storyblok: CMS appapps/sanity: CMS apppackages/ui: UI components library, shared between both CMS appspackages/eslint-config: shared eslint configurationspackages/ts-config: shared ts-config configurationpackages/tailwind-config: shared tailwind configurationThe website structure follows a clear hierarchical composition:
Pages
Sections
Base Components
RichText component has additional functionality. It allows to add sections inside, which gives ability to combine sections with text.
pnpm gen
- UI: Create a new UI component- Storyblok: Create a new content section- Sanity: Create a new content section
cd apps/storyblok
or
cd apps/sanity
pnpm sb-loginpnpm gen:types
cd apps/storyblok
or
cd apps/sanity
pnpm gen:types
git clone https://github.com/focusreactive/cms-kit
cd cms-kit
pnpm install
.env and .env.local file with proper data:Create .env and .env.local files in project folder (apps/sanity or apps/storyblok) and add the following variables:
.env
REPO_PROD_BRANCH="main"REPO_TYPE="github"REPO_ID="[repo id]"REPO_NAME="[nickname]/[repo name]"
Storyblok project
.env.local
NEXT_PUBLIC_DOMAIN="https://localhost:4050"NEXT_PUBLIC_IS_PREVIEW="true"NEXT_PUBLIC_STORYBLOK_TOKEN="[storyblok space preview token]"NEXT_PUBLIC_STORYBLOK_API_GATE="https://api.storyblok.com/v2/cdn"
Sanity project
.env.local
NEXT_PUBLIC_BASE_URL="http://localhost:3000"NEXT_PUBLIC_SANITY_PROJECT_ID="[project id]"NEXT_PUBLIC_SANITY_DATASET="production"SANITY_API_READ_TOKEN="[read token]"
pnpm dev
Happy hacking 👾