@goodfellow-cms/registry

中文文档
0.9.0发布于 2026/11/01MITES Module零依赖构建来源已验证

Goodfellow CMS's block registry: blocks built with shadcn/ui, which sites install from the admin panel.

原始使用文档
文档目录8 节
  1. How a block gets into a site
  2. Publishing your own registry
  3. Items
  4. Packages
  5. Writing the blocks
  6. Letting a site use it
  7. Making it easy to find
  8. Working on this registry

@goodfellow-cms/registry

Goodfellow's block registry: blocks built with shadcn/ui, and a few built with Tailwind alone for some sites only, which a site's admins add and remove on the admin panel's Blocks screen, with no developer. It's also the reference for anyone publishing a registry of Goodfellow blocks built with another component library.

BlockCategoryRecommended
HeroPage sectionsYes
CardsPage sectionsYes
Call to actionPage sectionsYes
TestimonialsPage sectionsYes
NoticePage sectionsYes
Pricing tablePage sections
FAQInteractiveYes
TabsInteractiveYes
News feedPage sections
MapPage sections
Social linksPage sections
PanelPage sections
Image carouselInteractive
Slideshow with quick linksInteractive
Content with section linksNavigation
PeoplePage sections
LogosPage sections
NumbersPage sections
TimelinePage sections
CountdownInteractive
CommentsInteractive
Custom HTMLAdvanced

New sites made with create-goodfellow start with the recommended blocks unless the admin chooses "Built-in blocks only".

How a block gets into a site

Adding a block copies its code into the site, as npx shadcn add would, in one publish:

  • the block's own files to blocks/installed/<name>/;
  • the shadcn components it uses to components/ui/, and any other shared code to components/, lib/ or hooks/, unless the site already has them;
  • a record of what was added, blocks/installed/installed.json, with a hash of every file written;
  • blocks/installed/index.ts, which the site's goodfellow.config.tsx imports and which lists every installed block.

The editor offers the block once the site has been rebuilt with it, which the host does after the publish (and goodfellow dev or next dev do straight away). Removing a block is refused while any page, collection page design, header or footer uses it. Removing deletes the files it added, except those someone has changed since or that another installed block uses.

The admin panel installs a release of this registry that matches its own: https://cdn.jsdelivr.net/npm/@goodfellow-cms/registry@<version>/r/{name}.json. In development, goodfellow dev and next dev serve the copy in the site's node_modules.

Publishing your own registry

A Goodfellow block registry is a shadcn registry whose block items follow a few extra rules. Build it with npx shadcn build and host the files anywhere that allows requests from browsers (CORS), such as GitHub Pages, npm through jsDelivr, or your own site.

Items

A block is a registry:block item with meta.goodfellow:

{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "acme-gallery",
  "type": "registry:block",
  "title": "Gallery",
  "description": "Pictures in a grid that open larger when clicked.",
  "registryDependencies": ["@acme/dialog"],
  "dependencies": ["radix-ui"],
  "files": [
    { "path": "blocks/acme-gallery/block.tsx", "type": "registry:block", "content": "…" },
    { "path": "blocks/acme-gallery/gallery-grid.tsx", "type": "registry:component", "content": "…" }
  ],
  "meta": {
    "goodfellow": {
      "category": "Pictures",
      "recommended": false,
      "image": "images/acme-gallery.png",
      "version": "1.2.0"
    }
  }
}
  • name becomes the block's key in the site's content, so never change it once published. Use lowercase letters, numbers and dashes, and start names with your registry's own prefix so they don't clash with other registries' blocks.
  • title and description are what admins see on the Blocks screen. Write them for people who aren't developers.
  • meta.goodfellow.category is the group the block is listed under, on the Blocks screen and in the editor. recommended marks blocks a new site should start with. image is a picture of the block, relative to the item's address. version is recorded in the site when the block is added.
  • Files: the item has exactly one registry:block file, whose default export is the block's Puck ComponentConfig. Every other file of the item goes into the block's folder too (blocks/installed/<name>/), so import them with relative paths (./gallery-grid). Items without meta.goodfellow, such as shared components, are dependencies: their files go to components/ui/ (registry:ui), components/ (registry:component), lib/ (registry:lib) or hooks/ (registry:hook), and blocks import them as @/components/ui/dialog and so on. A file's target can name another place within those folders. Other file types, and files elsewhere in the site, are refused.
  • registryDependencies name items as @namespace/name, or as a plain name for shadcn/ui's own components ("button"), as with the shadcn CLI.
  • registry.json, at the same address as the items (…/r/registry.json for …/r/{name}.json), lists them, so the Blocks screen can show them without loading every item.

Packages

The admin panel can't install npm packages, so every site includes the same set and blocks can use only those. Besides react, @goodfellow-cms/core, @goodfellow-cms/react and @puckeditor/core, which every site has, they are class-variance-authority, clsx, cn, embla-carousel-react, lucide-react, radix-ui, tailwind-merge and tw-animate-css. An item whose dependencies name anything else can't be added. To suggest a package for the list, open an issue.

Writing the blocks

Registry blocks follow the same rules as any Goodfellow block (see AGENTS.md):

  • Every block has a className prop (className: classNameField), applied to its outermost element and combined with cx() from @goodfellow-cms/react, last.
  • Use the theme's classes (bg-primary, text-muted-foreground, rounded-lg), which shadcn's components use too, so blocks follow the site's colors and fonts.
  • Give it words to be found by in the editor's block search, besides its label: export default withKeywords(block, ["faq", "questions"]) from @goodfellow-cms/react, lowercase. It can wrap withParts(), or the other way round.
  • Name the block's parts, so a site's theme can restyle them: const part = useParts() at the start of render, then className={part("gf-my-block-title", "text-xl font-bold", className)} on each part (the block's own classes, then anything an editor chose, className last), and declare them with what owners call them: export default withParts(block, { "gf-my-block-title": "Title" }). Start every name with gf- and the item's name, so they never clash with another block's, and never rename or remove one once it's published, since themes refer to them. Client Components get their parts' classes as plain props from the block, as shadcn-faq does.
  • Render links and images with SiteLink and SiteImage from @goodfellow-cms/react, and image fields with mediaField(). To style a link as a button, give SiteLink the classes from shadcn's buttonVariants().
  • Labels and options are for non-technical people: "Space above and below", not "padding-y".
  • render uses no hooks besides useSite(). Interactive parts go in a file starting with "use client", which gets plain values and content (children, rich text) only.
  • One Client Component per interactive part. Sites built with goodfellow build run each Client Component a block renders as its own small React app (an island), and islands don't share React context. Components whose parts talk to each other through context, as Radix's Accordion, AccordionItem and AccordionContent do, must all be put together inside one "use client" file, which the block renders with its content as props. See site/blocks/installed/shadcn-faq/ here.
  • Keep content in the page. Hidden content, such as closed answers or other tabs, should still be in the HTML (Radix's forceMount, hidden with CSS), so search engines and visitors without JavaScript see it.
  • Prefer HTML and CSS where they're enough: a <details> element rather than a Client Component, since a page with a Client Component loads React.
  • Say when a Client Component works with Preact, with export const worksWithPreact = true in its "use client" file, once you've tried it there. Sites whose Client Components all say so run them with Preact's preact/compat instead of React, about a tenth of its size; one that doesn't keeps a site on React. Every interactive block here says so, and Goodfellow's tests try each with Preact.

Letting a site use it

Admins can only add blocks from registries the site's developer trusts, since a block's code runs in the admin panel with the editor's access to the site. Add yours to the site's goodfellow.config.tsx, and its blocks appear on the Blocks screen beside Goodfellow's:

export default defineConfig({
  blocks: { ...blocks, ...installedBlocks },
  registries: { "@acme": "https://acme.example/r/{name}.json" },
});

Making it easy to find

Call the registry's repository goodfellow-blocks-<name> and give it the goodfellow-blocks topic on GitHub or GitLab, so searching either finds it, as goodfellow-plugin-<name> and goodfellow-theme-<name> do for plugins and themes. You can also ask for it to be listed in shadcn's directory of registries. This registry is the exception, since it's released with Goodfellow.

Working on this registry

  • registry.json lists the blocks, whose files are in site/blocks/installed/, laid out as they'll be in a site.
  • site/components/ui/ and shadcn.json are a snapshot of the shadcn/ui components the blocks use, so a release always installs the same code. pnpm --filter @goodfellow-cms/registry update-shadcn (scripts/snapshot.mjs) fetches them again; review and commit what it writes. Don't edit the snapshot by hand.
  • pnpm build (scripts/build.mjs) writes r/, which is what's published: an item per block and component, with its files, and r/registry.json.
  • The tests check that every item is valid, uses only the allowed packages, installs with every file it imports, and renders.

The shadcn/ui components are © shadcn, under the MIT license in LICENSE-shadcn.md.

版本与发布记录

@goodfellow-cms/registry 共发布 10 个版本,首次发布于 2026/10/09;过去 12 个月发布了 10 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.9.0latest2026/11/012 天前
0.8.02026/10/304 天前
0.7.02026/10/295 天前
0.6.02026/10/277 天前
0.5.02026/10/259 天前
0.4.02026/10/1816 天前

关于 @goodfellow-cms/registry 的常见问题

@goodfellow-cms/registry 是什么?

Goodfellow CMS的块注册表:用shadcn/ui构建的块,站点从管理面板安装。

如何安装 @goodfellow-cms/registry?

在项目目录运行 npm install @goodfellow-cms/registry,或使用 pnpm add / yarn add / bun add。

@goodfellow-cms/registry 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/goodfellow-cms__registry 是否存在。

@goodfellow-cms/registry 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@goodfellow-cms/registry 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.23.4 || ^24.22.1 || >=26.12.1。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@goodfellow-cms/registry 可以商用吗?

@goodfellow-cms/registry 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@goodfellow-cms/registry 还在维护吗?

最新版本 0.9.0 发布于 2026/11/01(2 天前);至今共发布 10 个版本,其中过去 12 个月发布了 10 个;首次发布于 2026/10/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。