Advanced Block Features

Requirements, layout blocks, styling, SSR, GraphQL, and @cmssy/types.

Last updated: March 20, 2026

Block Requirements

Use requires to request platform features:

defineBlock({
  name: "Member Dashboard",
  requires: {
    auth: true,
    language: true,
    workspace: true,
    modules: ["forms"],
    features: ["ai-generation"],
    permissions: ["pages:edit"]
  },
  schema: { ... }
});

Modules

Workspace modules gate blocks by what the workspace actually has installed / enabled. All six values are accepted by the backend today; some are still in development.

ModuleStatusWhat it gates
formsShippedForm Builder + submission storage. See Forms.
analyticsPartialVisitor analytics + script injection. See Analytics Scripts (planned doc).
newsletterPartialNewsletter subscription list + email campaign sending.
pimPlannedProduct Information Management. Tracked in CMS-28.
crmPlannedCustomer relationship & business tools. CMS-21.
ecommercePlannedCart, checkout, orders, inventory. Depends on PIM. CMS-31.

Feature flags

Feature flags gate blocks by opt-in platform capabilities that may be disabled per plan or per workspace.

FlagStatusWhat it gates
ai-generationShippedAI-assisted content generation inside blocks (draft copy, translations, etc.).
ai-translationShippedPer-field auto-translation between enabled languages.
a-b-testingPlannedExperiment framework for content variants. Listed on Roadmap (Planned).

As of @cmssy/types 0.11.0, advanced-seo and personalization were removed from the enum — they were placeholders with no backend and no roadmap entry. Blocks referencing them will fail typecheck after upgrading.

Permissions

The permissions field takes any permission string (e.g. pages:edit, models:edit, forms:create). The block only renders when the current user has ALL listed permissions. Enforced server-side. See Members & Roles for the full permission list.


Layout Blocks


Layout Blocks

Layout blocks render in fixed page positions (header, footer, sidebars):

defineBlock({
  name: "Site Header",
  layoutPosition: "header",
  schema: {
    logo: { type: "media", label: "Logo" },
    links: {
      type: "repeater",
      label: "Navigation Links",
      schema: {
        label: { type: "singleLine", label: "Label" },
        url: { type: "link", label: "URL" }
      }
    }
  }
});

Positions: header, footer, sidebar_left, sidebar_right, top, bottom


Styling with Tailwind v4

Block CSS (src/index.css)

@import "../../../styles/main.css";

Global Styles (styles/main.css)

@import "tailwindcss";

@theme {
  --color-background: oklch(1 0 0);
  --color-foreground: oklch(0.145 0 0);
  --color-primary: oklch(0.205 0 0);
}

Container Component

import { Container } from "../../../components/container";

export default function MyBlock({ content }) {
  return (
    <section className="py-20">
      <Container><h2>{content.heading}</h2></Container>
    </section>
  );
}

Server-Side Rendering (SSR)

Export __ssr for server rendering (no hooks, no browser APIs):

export const __ssr = function HeroSSR({ content }) {
  return <section><h1>{content.heading}</h1></section>;
};

export default function Hero({ content }) {
  const [count, setCount] = useState(0);
  return (
    <section>
      <h1>{content.heading}</h1>
      <button onClick={() => setCount(c => c + 1)}>{count}</button>
    </section>
  );
};

GraphQL in Blocks

"use client";

export default function ContactForm({ content, context }) {
  const workspaceId = context?.workspace?.id;

  const handleSubmit = async (formData) => {
    await fetch("/api/graphql", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        query: `mutation Submit($workspaceId: ID!, $input: FormSubmissionInput!) {
          submitForm(workspaceId: $workspaceId, input: $input) { success }
        }`,
        variables: { workspaceId, input: formData }
      })
    });
  };
}

@cmssy/types Package

pnpm add -D @cmssy/types

Key exports:

  • BlockProps<T> - Block props interface
  • PlatformContext - Full context type
  • BlockConfig, FieldConfig - Config types
  • FieldTypeValueMap, FieldValue, FIELD_TYPE_DEFAULTS - Type mapping
  • BlockAuthContext, BlockI18nContext - Context types
  • LayoutPosition, BlockRequires - Enums and requirements
Advanced Block Features — Cmssy CLI | Cmssy