ForgeJo

Blocks

PreviousNext

Contribute components to the blocks library.

We are inviting the community to contribute to the blocks library. Share your components and blocks with other developers and help build a library of high-quality, reusable components.

We'd love to see all types of blocks: applications, marketing, products, and more.

Setup your workspace

Fork the repository

Clone the repository from ForgeJo:

git clone https://code.cloud.cosm-lab.science/COSM-lab/cosm-ui-kit

Then navigate into the apps/docs directory.

Create a new branch

git checkout -b username/my-new-block

Install dependencies

From the repository root:

pnpm install

Start the dev server

pnpm dev

The docs site runs at http://localhost:34400.

Add a block

A block can be a single component (eg. a variation of a ui component) or a complex component (eg. a dashboard) with multiple components, hooks, and utils.

Create a new block

Create a new folder in the registry/new-york-v4/blocks directory. Make sure the folder is named in kebab-case.

apps
└── docs
    └── registry
        └── new-york-v4
            └── blocks
                └── dashboard-01

Add your block files

Add your files to the block folder. Here is an example of a block with a page, components, hooks, and utils.

dashboard-01
└── page.tsx
└── components
    └── hello-world.tsx
    └── example-card.tsx
└── hooks
    └── use-hello-world.ts
└── lib
    └── format-date.ts

Add your block to the registry

Add your block definition to _registry.ts

To add your block to the registry, add your block definition to registry/new-york-v4/blocks/_registry.ts.

This follows the registry schema at https://ui.shadcn.com/schema/registry-item.json.

registry/new-york-v4/blocks/_registry.ts
export const blocks = [
  // ...
  {
    name: "dashboard-01",
    description: "A simple dashboard with a hello world component.",
    type: "registry:block",
    registryDependencies: ["input", "button", "card"],
    dependencies: ["zod"],
    files: [
      {
        path: "blocks/dashboard-01/page.tsx",
        type: "registry:page",
        target: "app/dashboard/page.tsx",
      },
      {
        path: "blocks/dashboard-01/components/hello-world.tsx",
        type: "registry:component",
      },
    ],
    categories: ["dashboard"],
  },
]

Make sure you add a name, description, type, registryDependencies, dependencies, files, and categories.

Run the build script

pnpm registry:build

View your block

Once the build script is finished, you can view your block at http://localhost:34400/blocks/dashboard or a full screen preview at http://localhost:34400/view/dashboard-01.

Build your block

You can now build your block by editing the files in the block folder and viewing the changes in the browser.

If you add more files, make sure to add them to the files array in the block definition.

Publish your block

Once you're ready to publish your block, you can submit a pull request to the main repository.

Run the build script

pnpm registry:build

Capture a screenshot

pnpm registry:capture

Submit a pull request

Commit your changes and submit a pull request to the main repository.

Your block will be reviewed and merged. Once merged it will be published to the website.

Categories

The categories property is used to organize your block in the registry.

Add a category

If you need to add a new category, you can do so by adding it to the registryCategories array in lib/categories.ts.

lib/categories.ts
export const registryCategories = [
  // ...
  {
    name: "Input",
    slug: "input",
    hidden: false,
  },
]

Guidelines

Here are some guidelines to follow when contributing to the blocks library.

  • The following properties are required for the block definition: name, description, type, files, and categories.
  • Make sure to list all registry dependencies in registryDependencies. A registry dependency is the name of the component in the registry eg. input, button, card, etc.
  • Make sure to list all dependencies in dependencies. A dependency is the name of the package in the registry eg. zod, sonner, etc.
  • If your block has a page (optional), it should be the first entry in the files array and it should have a target property. This helps place the page in the correct location for file-based routing.
  • Imports should always use the @/registry path. eg. import { Input } from "@/registry/new-york-v4/input"