Scaffold a new page builder block for Turbo Start Sanity end-to-end — Sanity schema, GROQ projection, styled React component, Markdown serializer, tests, and all registrations.

MITAuto-check passedFrontend & Design

Install New Block

skills CLI
$ npx skills add robotostudio/turbo-start-sanity --skill new-block -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install robotostudio/turbo-start-sanity new-block --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/robotostudio/turbo-start-sanity.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/new-block .claude/skills/new-block && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
new-block
GitHub stars
182
Token cost
~2.8k tokens
SKILL.md length
964 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

Scaffold a new page builder block for Turbo Start Sanity end-to-end — Sanity schema, GROQ projection, styled React component, Markdown serializer, tests, and all registrations.

  • Works in 8 steps: Create the block directory → Register in the package root → Add the GROQ projection to the shared… → …
  • Scaffold a new page builder block
  • SKILL.md covers Inputs, Steps and Checklist
  • Calls pnpm

What it does

New Block is an agent skill from robotostudio/turbo-start-sanity. Scaffold a new page builder block for Turbo Start Sanity end-to-end — Sanity schema, GROQ projection, styled React component, Markdown serializer, tests, and all registrations. Use when asked to add, create, or scaffold a new page builder block, section, or content module (e.g. "add a testimonials block", "create a pricing table section", "/new-block stats").

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering React components and Project scaffolding. It works with Turborepo, Next.js and React. The repository describes itself as: Sanity + Next.js page-builder template. The licence is MIT.

When your agent uses it

  • Scaffold a new page builder block
  • Content module (e.g

Example prompts

  • “add a testimonials block”
  • “create a pricing table section”
  • “/new-block stats”
  • “/new-block”

Workflow steps

8 steps, taken from the step headings in SKILL.md.

  1. Create the block directory
  2. Register in the package root
  3. Add the GROQ projection to the shared query
  4. Regenerate Sanity types
  5. Register the web renderer
  6. Register the Markdown serializer
  7. Studio insert-menu thumbnail
  8. Verify

What it can do on your machine

Read from SKILL.md and the folder at commit 8155b99. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • sanitypress.dev

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

New Block loads about 2.8k tokens when it runs. Until then it costs about 93 tokens; SKILL.md has 964 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~93
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from robotostudio/turbo-start-sanity at commit 8155b99, republished under its MIT licence (© robotostudio). 964 words, ~2,762 tokens.

Download SKILL.mdSave it as .claude/skills/new-block/SKILL.md (or your agent's skills folder).
name
new-block
description
Scaffold a new page builder block for Turbo Start Sanity end-to-end — Sanity schema, GROQ projection, styled React component, Markdown serializer, tests, and all registrations. Use when asked to add, create, or scaffold a new page builder block, section, or content module (e.g. "add a testimonials block", "create a pricing table section", "/new-block stats").

New Page Builder Block

Scaffold a complete page builder block in one pass. Every block touches three workspaces — packages/sanity-blocks (source of truth), packages/sanity (GROQ), and apps/web (rendering) — plus generated types. Studio registration is automatic once the schema joins blockSchemas.

Credit: adapted for Turbo Start Sanity from Michael's /new-module skill for SanityPress — https://sanitypress.dev/blog/new-module-skill-claude-code.

Inputs

Before writing files, establish:

  1. Block name — two forms, used consistently everywhere:

    • camelCase schema type name, e.g. pricingTable (matches _type)
    • kebab-case directory/file name, e.g. pricing-table

    Check blockSchemas in packages/sanity-blocks/src/sanity-blocks.ts first — if the name is taken you are editing a block, not adding one.

  2. Fields — what content editors manage. If the request doesn't say, ask. Reuse shared field helpers from packages/sanity-blocks/src/internal/schema-fields.ts (buttonsField, definePortableTextField, etc.) before defining new shapes.

  3. An icon — all ten block schemas import one from lucide-react; match them. Then add a matching stub to packages/sanity-blocks/src/internal/testing/lucide-react.mock.tsx: lucide-mock-coverage.test.ts greps src/ for from "lucide-react" and fails the whole suite on any icon with no stub, and an unstubbed icon renders as undefined ("Element type is invalid") in every component test. (@sanity/icons is not scanned, so it needs no stub — but it is used for Studio UI, not block schemas.)

Study the closest existing block in packages/sanity-blocks/src/ (e.g. cta for text+buttons, showcase-grid for card grids, faq-accordion for nested arrays) and mirror its structure and idioms.

Steps

Work through all steps in order — a block missing any registration renders as "Component not found" on the web or blank in .md output.

1. Create the block directory

packages/sanity-blocks/src/<kebab>/ containing:

<kebab>.schema.ts — the Sanity schema:

ts
import { Table } from "lucide-react";
import { defineField, defineType } from "sanity";

export const pricingTableSchema = defineType({
  name: "pricingTable",
  type: "object",
  icon: Table,
  fields: [
    defineField({
      name: "title",
      title: "Title",
      type: "string",
      description: "The large text that is the primary focus of the block",
    }),
    // ...more fields — every field needs a `description` written for
    // non-technical editors
  ],
  preview: {
    select: { title: "title" },
    prepare: ({ title }) => ({
      title,
      subtitle: "Pricing Table",
    }),
  },
});

<kebab>.groq.ts — the GROQ projection, reusing fragments from ../internal/groq-fragments (richTextFragment, buttonsFragment, imageFragment, …). Don't expand images unless the component needs the expanded fields:

ts
import { buttonsFragment, richTextFragment } from "../internal/groq-fragments";

export const pricingTableGroqProjection = /* groq */ `
  _type == "pricingTable" => {
    ...,
    ${richTextFragment},
    ${buttonsFragment},
  }
`;

index.tsx — the styled React component (Tailwind v4 + @workspace/ui). Define an explicit props interface with all fields optional/nullable — the web app asserts the generated query type onto it, so looser is safer. Conventions: wrap in <section> with its own <div className="container"> rail, prefer grid over flex unless two siblings, use SanityImage / SanityButtons / RichText / BlockEyebrow from @workspace/sanity-blocks/internal/*, and give the <section> the shared block-section class (hero and logo-cloud are the two that opt out, both with their own full-bleed layout).

The hardcoded id is the repo-wide convention (id="cta", id="faq", id="showcase", …) and doubles as the in-page anchor. It assumes one instance per page: the page builder is an unconstrained array, so an editor who adds the same block twice gets a duplicate id. Keep the convention, and drop the id if the block is one an editor is likely to repeat:

tsx
import { BlockEyebrow } from "@workspace/sanity-blocks/internal/block-eyebrow";
import type { RichTextValue } from "@workspace/sanity-blocks/internal/rich-text";
import { RichText } from "@workspace/sanity-blocks/internal/rich-text";

export interface PricingTableProps {
  eyebrow?: string | null;
  richText?: RichTextValue;
  title?: string | null;
}

export function PricingTable({
  eyebrow,
  title,
  richText,
}: Readonly<PricingTableProps>) {
  return (
    <section className="block-section" id="pricing-table">
      <div className="container">
        <BlockEyebrow eyebrow={eyebrow} />
        <h2 className="text-balance font-semibold text-3xl md:text-5xl">
          {title}
        </h2>
        <RichText richText={richText} />
      </div>
    </section>
  );
}

markdown.ts — the Markdown serializer, composing helpers from ../internal/markdown (headingToMarkdown, eyebrowToMarkdown, buttonsToMarkdown, joinSections) and ../internal/portable-text-to-markdown.

MarkdownBlock in ../internal/markdown.ts is one wide interface of optional fields accumulated across every block, not a per-block type — it already carries items, cards, logos, socials, testimonial and more. If the serializer reads a field that is not yet there, add it — and any row type it needs — to MarkdownBlock in the same edit, or the serializer will not compile:

ts
import {
  type MarkdownBlock,
  type MarkdownOptions,
  headingToMarkdown,
  joinSections,
} from "../internal/markdown";
import { portableTextToMarkdown } from "../internal/portable-text-to-markdown";

export function pricingTableToMarkdown(
  block: MarkdownBlock,
  options: MarkdownOptions
): string {
  return joinSections([
    headingToMarkdown(block.title, 2),
    portableTextToMarkdown(block.richText, options),
  ]);
}

<kebab>.test.tsx — render the component with renderToStaticMarkup and assert primary content appears (see cta/cta.test.tsx).

<kebab>-markdown.test.ts — cover: empty block returns "", fields serialize joined by blank lines, markdown chars are escaped, and no HTML/JSX leaks (expect(result).not.toMatch(/<\/?[A-Za-z]/) — the \/? also catches a stray closing tag like </p>, which the bare /<[A-Za-z]/ in the existing tests misses). Mirror cta/cta-markdown.test.ts for the rest.

2. Register in the package root

In packages/sanity-blocks/src/sanity-blocks.ts: import the schema, add a named export, and append it to the blockSchemas array. This alone registers the block in Studio — apps/studio/schemaTypes/index.ts and definitions/pagebuilder.ts both map over blockSchemas.

No package.json edit is needed: the package's wildcard exports (./*/index, ./*.groq, ./*.schema) already cover the new directory.

Show full SKILL.md (370 more words)Show less
3. Add the GROQ projection to the shared query

In packages/sanity/src/query.ts: import <camel>GroqProjection from @workspace/sanity-blocks/<kebab>/<kebab>.groq and add it to pageBuilderFragment alongside the existing projections.

4. Regenerate Sanity types
bash
pnpm --filter studio extract
pnpm type

Both commands are required, in that order. pnpm type runs sanity typegen generate, which reads the committed apps/studio/schema.json — it does not look at the schema source. Only sanity schema extract refreshes that file. Run pnpm type alone and the generated types silently keep the old schema, leaving PagebuilderType<"<camel>"> unresolvable in step 5 (never paper over that with a cast — it means extract didn't run).

Together they update packages/sanity/src/sanity.types.ts; the web app's PagebuilderType<"<camel>"> in apps/web/src/types.ts picks the new block up automatically — never hand-write Sanity shapes.

5. Register the web renderer

In apps/web/src/components/pagebuilder.tsx: import the component from @workspace/sanity-blocks/<kebab>/index and add a case to renderBlockComponent:

tsx
case "pricingTable":
  return <PricingTable {...(block as PagebuilderType<"pricingTable">)} />;
6. Register the Markdown serializer

In packages/sanity-blocks/src/internal/page-builder-to-markdown.ts: import <camel>ToMarkdown from the block's markdown.ts and add a case to the blockToMarkdown switch. Without this the block renders blank in .md content negotiation (/page.md, Accept: text/markdown).

7. Studio insert-menu thumbnail

The page builder insert menu looks for apps/studio/static/thumbnails/preview-<kebab>.png, synced at install time from packages/sanity-blocks/src/<kebab>/thumbnail.png by pnpm --filter studio sync-thumbnails. The generate-thumbnails-agentic skill does this, or note in the PR that the thumbnail is pending — the block works without it; the menu tile just has no preview image.

8. Verify
bash
pnpm --filter @workspace/sanity-blocks test   # component + markdown tests
pnpm check-types
pnpm format                                   # Biome, auto-fix
pnpm lint

check-types does not catch a missing registration. Both switches — renderBlockComponent and blockToMarkdown — end in a default arm with no never exhaustiveness guard, so a missing case type-checks clean and only shows up at runtime as the "Component not found for block type" placeholder, or as a blank section in .md output. Grep for the two case arms instead:

bash
grep -rn 'case "<camel>":' apps/web/src/components/pagebuilder.tsx \
  packages/sanity-blocks/src/internal/page-builder-to-markdown.ts

One hit per file. Fewer means a registration is missing.

Checklist

  • packages/sanity-blocks/src/<kebab>/ — schema, groq, index.tsx, markdown.ts, two test files
  • Every schema field has a description
  • Schema icon stubbed in internal/testing/lucide-react.mock.tsx
  • Exported + appended to blockSchemas in sanity-blocks.ts
  • Projection added to pageBuilderFragment in packages/sanity/src/query.ts
  • pnpm --filter studio extract then pnpm type — types include the block
  • case added in renderBlockComponent (apps/web/src/components/pagebuilder.tsx)
  • case added in blockToMarkdown (internal/page-builder-to-markdown.ts)
  • Any new field the serializer reads added to MarkdownBlock
  • Thumbnail added or flagged as pending
  • Both case arms grepped for — check-types will not flag a missing one
  • Tests, check-types, and lint pass

© robotostudio, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/new-block of robotostudio/turbo-start-sanity.

Open the folder on GitHubat commit 8155b99

Compare with similar skills

New Block next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

New Block compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
New Block this skillrobotostudio/turbo-start-sanity182—~2.8kAutomated safety check: PassMIT
Senior Frontendalirezarezvani/claude-skills28k5 repos~3.9kAutomated safety check: PassMIT
Senior Frontendborghei/Claude-Skills881—~1.7kAutomated safety check: PassMIT
Chakra UI v3 Builderchakra-ui/chakra-ui41k—~3.1kAutomated safety check: PassMIT
React View Transitions Guidevercel-labs/next-beats16710 repos~3.1kAutomated safety check: PassMIT
Vercel React Best Practicessanity-io/sanity6.4k130 repos~1.6kAutomated safety check: PassMIT

Similar skills

  • Senior Frontend

    alirezarezvani/claude-skills

    Frontend development skill for React, Next.js, TypeScript, and Tailwind CSS applications.

    28k GitHub starsUsed in 5 repos~3.9k tokens
    Frontend & DesignAuto-check passed
  • Senior Frontend

    borghei/Claude-Skills

    Frontend development for React, Next.js, TypeScript, and Tailwind CSS.

    881 GitHub stars~1.7k tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Chakra UI v3 Builder

    chakra-ui/chakra-ui

    Builds responsive, accessible Chakra UI v3 components and layouts, sets up Chakra in new or existing projects, and designs themes with tokens, semantic tokens and recipes.

    41k GitHub stars~3.1k tokensUpdated 2 days ago
    Frontend & DesignAuto-check passed
  • React View Transitions Guide

    vercel-labs/next-beats

    Official

    Guides implementing animated page and state transitions in React with the native View Transition API, covering shared elements, list reorders and directional navigation.

    167 GitHub starsUsed in 10 repos~3.1k tokens
    Frontend & DesignAuto-check passed
  • Official

    React and Next.js performance optimization guidelines from Vercel Engineering.

    6.4k GitHub starsUsed in 130 repos~1.6k tokens
    Frontend & DesignAuto-check passed
  • GSAP for React

    greensock/gsap-skills

    Shows how to run GSAP animations in React and Next.js with the useGSAP hook, refs, scoped selectors and automatic cleanup on unmount.

    16k GitHub starsUsed in 4 repos~1.6k tokens
    Frontend & DesignAuto-check passed

More from robotostudio/turbo-start-sanity

  • Sanity Best Practices

    robotostudio/turbo-start-sanity

    Sanity development best practices for schema design, GROQ queries, TypeGen, Visual Editing, images, Portable Text, Studio structure, localization, migrations, Sanity Functions, Blueprints, and…

    182 GitHub stars~940 tokensUpdated 3 days ago
    Auto-check passed
  • Sanity Live Cache Components

    robotostudio/turbo-start-sanity

    Integrates Sanity Live with Next.js Cache Components in next-sanity v13+ apps.

    182 GitHub stars~2.8k tokensUpdated 3 days ago
    Auto-check passed

Questions about New Block

What does New Block do?

Scaffold a new page builder block for Turbo Start Sanity end-to-end — Sanity schema, GROQ projection, styled React component, Markdown serializer, tests, and all registrations. New Block is an agent skill from robotostudio/turbo-start-sanity. Scaffold a new page builder block for Turbo Start Sanity end-to-end — Sanity schema, GROQ projection, styled React component, Markdown serializer, tests, and all registrations.

When should I use New Block?

New Block fits situations like: scaffold a new page builder block; content module (e.g.

How do I install New Block in Claude Code?

Run `npx skills add robotostudio/turbo-start-sanity --skill new-block -a claude-code`. Or copy the skill folder (.agents/skills/new-block in robotostudio/turbo-start-sanity) into .claude/skills/new-block in your project. Claude Code loads it when a task matches its description.

How do I install New Block in Codex?

Run `npx skills add robotostudio/turbo-start-sanity --skill new-block -a codex`. Or copy the skill folder (.agents/skills/new-block in robotostudio/turbo-start-sanity) into .agents/skills/new-block in your project. Codex loads it when a task matches its description.

Can I use New Block in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add robotostudio/turbo-start-sanity --skill new-block -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/new-block, .gemini/skills/new-block, .github/skills/new-block and .opencode/skills/new-block in your project.

What does New Block need to run?

Going by SKILL.md and its folder, New Block needs the command-line tools its instructions call (pnpm).

Does New Block access the network?

SKILL.md names 1 domain. As links in the text: sanitypress.dev. This is read from the text; nothing was executed.

Is New Block safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does New Block use?

New Block is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does New Block use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to New Block?

Skills that share tags, products or a category with New Block: Senior Frontend (alirezarezvani/claude-skills, 28k stars), Senior Frontend (borghei/Claude-Skills, 881 stars), Chakra UI v3 Builder (chakra-ui/chakra-ui, 41k stars) and React View Transitions Guide (vercel-labs/next-beats, 167 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains New Block?

robotostudio (a GitHub organization) maintains it in robotostudio/turbo-start-sanity, which has 182 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 5, 2026.

Source: robotostudio/turbo-start-sanity on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.