All Systems Operational
Powered By
profound-logo
profound-logoProfound CMS
⌘K
Admin

Component Zod Pull

Pull zod description of your components at compile time using a script

Continue Reading
Previous‹Json And Claude Code

Hybrid

Setup Hybrid CMS ProjectParametric Pages with ComponentsTypes of ComponentsSetup server sent events (SSE) content refetchSetup admin panel proxyStatic Rendering with Edit Mode SupportScripting in Template BuilderGetting Started Hybrid

Headless

Quick startSplit Screen JSON Component Builder with LLMComponent Zod Pull

MCP

MCP with Claude Code / Codex

Feature

Documentation Site TemplateFeature Template BuilderTranslation ServiceOrganizations & Website Heirarchy

Motivation

Our Approch

Terminology

'Hybrid' vs 'Headless'

This feature allows you to get your schema description in the form of a type safe "Zod" description which provides TS-first schema validation and static type inference for your schema.

https://zod.dev

To pull our zod schema, we're going to load some dependencies and create a script which use some utilities from our cms-renderer

Let's start by our project structure

theme={null}
apps/
 web/
 app/
   page.tsx
 scripts/
   generated-schema.ts // this is where our script lives

Now we will edit this generated-schema.ts file

generated-schema.ts theme={null}
import { fetchAllCustomSchemaFields, saveZodSchemaCode } from 'cms-renderer/lib/custom-schemas';
import { cmsConfig } from '../lib/cms-config'; // importing my config

async function main() {
  const { cmsUrl, websiteId } = cmsConfig;

  if (!cmsUrl) {
    throw new Error(
      '[generate-schemas] NEXT_PUBLIC_CMS_API_URL is not set. Set it in your environment or .env file.'
    );
  }
  if (!websiteId) {
    throw new Error(
      '[generate-schemas] CMS_WEBSITE_ID is not set. Set it in your environment or .env file.'
    );
  }

  await saveZodSchemaCode(
    await fetchAllCustomSchemaFields(cmsConfig),
    './generated/cms-schemas.ts'
  );

  console.log('[generate-schemas] Done.');
}

main().catch((err) => {
 console.error('[generate-schemas] Failed:', err);
  process.exit(1);
});

Your CmsConfig should look like

theme={null}
export const cmsConfig = {
  cmsUrl: process.env.NEXT_PUBLIC_CMS_API_URL,
  apiKey: process.env.CMS_API_KEY,
  websiteId: '...',
};

Inside our package.json we define how to run the script and some dependencies

NOTE: If you don't have a tsconfig then you can remove the --tsconfig flag and its value

package.json theme={null}
{
  "name": "web",
  "version": "0.1.0",
  "type": "module",
  "private": true,
  "scripts": {
    "generate-schemas": "tsx --tsconfig tsconfig.json scripts/generate-schemas.ts",
    "...": "..."
  },

Now after we run

$ bun run generate-schemas
tsx --tsconfig tsconfig.json scripts/generate-schemas.ts
[generate-schemas] Done.

We should get similar output and we can see a new file in our project structure

theme={null}
apps/
 web/
 app/
   page.tsx
 scripts/
   generated-schema.ts // this is where our script lives
 generated/
   cms-schema.ts // generated zod schema

You can inspect inside and see how your schema looks like. To update this file you have to run the bun run generate-schemas command again which you can connect to your dev or build workflow.

We can then pull these zod objects in our page.tsx file like so

page.tsx theme={null}
import type { PetFoodPost, SiteConfig } from '@/generated/cms-schemas';
import { petFoodPostSchema } from '@/generated/cms-schemas';

// call petFoodPostSchema.parse(obj) for type safe parsing of objects

You can update your schema from the admin panel and pull the updated schema again for easy development

"dependencies": {
"cms-renderer": "0.3.1",
"zod": "^4.3.6",
"...": "..."
},
"devDependencies": {
"tsx": "^4.21.0",
"object-hash": "^3.0.0",
"...": "..."
}
}