DEV Community

Cover image for shadcn-ui/ui codebase analysis: How is “Blocks” page built — Part 1
Ramu Narasinga
Ramu Narasinga

Posted on • Edited on

1

shadcn-ui/ui codebase analysis: How is “Blocks” page built — Part 1

In this article, I discuss how Blocks page is built on ui.shadcn.com. Blocks page has a lot of utilities used, hence I broke down this Blocks page analysis into 5 parts.

  1. shadcn-ui/ui codebase analysis: How is “Blocks” page built — Part 1
  2. shadcn-ui/ui codebase analysis: How is “Blocks” page built — Part 2 (Coming soon)
  3. shadcn-ui/ui codebase analysis: How is “Blocks” page built — Part 3 (Coming soon)
  4. shadcn-ui/ui codebase analysis: How is “Blocks” page built — Part 4 (Coming soon)
  5. shadcn-ui/ui codebase analysis: How is “Blocks” page built — Part 5 (Coming soon)

In part 1, we will look at the following:

  1. Where to find blocks page code in the shadcn-ui/ui repository?
  2. getAllBlockIds function
  3. _getAllBlocks function

These function further call other utility functions that will be explained in the other parts.

Where to find blocks page code in the shadcn-ui/ui repository?

blocks/page.tsx is where you will find Blocks page related code in the shadcn-ui/ui repository

Just because it has only 10 lines of code does not mean it is a simple page, there is a lot going on behind these lines, especially in the lib/blocks.ts, but don’t worry, we will understand the utility functions used in depth later in this article and other parts as well.

BlocksPage gets the blocks from a function named getAllBlockIds() which is imported from lib/blocks and these blocks are mapped with a BlockDisplay component that shows blocks on the Blocks page. Let’s find out what is in getAllBlockIds()

getAllBlockIds function

The below code snippet is picked from lib/blocks.ts

export async function getAllBlockIds(
  style: Style\["name"\] = DEFAULT\_BLOCKS\_STYLE
) {
  const blocks = await \_getAllBlocks(style)
  return blocks.map((block) => block.name)
}
Enter fullscreen mode Exit fullscreen mode

This code snippet is self explanatory, style parameter gets a default value DEFAULT_BLOCKS_STYLE because in the Blocks page, we call getAllBlockIds without any params as shown below:

const blocks = await getAllBlockIds()
Enter fullscreen mode Exit fullscreen mode

But wait, what is the value in DEFAULT\_BLOCKS\_STYLE?

At line 14 in lib/blocks, you will find this below code:

const DEFAULT\_BLOCKS\_STYLE = "default" satisfies Style\["name"\]
Enter fullscreen mode Exit fullscreen mode

“default” satisfies Style[“name”], Style is from register/styles. I just admire the quality of Typescript written in this shadcn-ui/ui. So, _getAllBlocks gets called with a param named style that is initiated to “default”. So far, the code is straight forward. Let’s now understand what is in _getAllBlocks

_getAllBlocks function

The below code snippet is picked from lib/blocks.ts

async function \_getAllBlocks(style: Style\["name"\] = DEFAULT\_BLOCKS\_STYLE) {
  const index = z.record(registryEntrySchema).parse(Index\[style\])

  return Object.values(index).filter(
    (block) => block.type === "components:block"
  )
}
Enter fullscreen mode Exit fullscreen mode

Even though, getAllBlockIds from above calls this function with a parameter, this function still has a default value set to the style parameter.

const index = z.record(registryEntrySchema).parse(Index\[style\])
Enter fullscreen mode Exit fullscreen mode

Code above has the following:

z.record

Record schema in Zod are used to validate types such as Record. This is particularly useful for storing or caching items by ID.

registryEntrySchema

registryEntrySchema defines a schema for the blocks

export const registryEntrySchema = z.object({
  name: z.string(),
  description: z.string().optional(),
  dependencies: z.array(z.string()).optional(),
  devDependencies: z.array(z.string()).optional(),
  registryDependencies: z.array(z.string()).optional(),
  files: z.array(z.string()),
  source: z.string().optional(),
  type: z.enum(\[
    "components:ui",
    "components:component",
    "components:example",
    "components:block",
  \]),
  category: z.string().optional(),
  subcategory: z.string().optional(),
  chunks: z.array(blockChunkSchema).optional(),
})
Enter fullscreen mode Exit fullscreen mode

parse(Index[style])

parse is a schema method to check data is valid. If it is, a value is returned with full type information! Otherwise, an error is thrown.

Example:

const stringSchema = z.string();

stringSchema.parse("fish"); // => returns "fish"
stringSchema.parse(12); // throws error
Enter fullscreen mode Exit fullscreen mode

Index is imported from _registry_folder and contains all the components used in shadcn-ui/ui.

Looks like this file gets auto generated by scripts/build-registry.ts and this is also used in CLI package to add shadcn components into your project, more on this in the upcominhg articles.

Basically, we validate Index[“default”] against the registry schema to ensure the auto generated code is valid and is ready for further processing such as showing in blocks page.

_getAllBlocks filters the blocks based on the block type as shown below:

return Object.values(index).filter(
    (block) => block.type === "components:block"
  )
Enter fullscreen mode Exit fullscreen mode

This is how you are able to see components that are specific to Blocks page.

Conclusion:

We looked at two important module functions named getAllBlockIds and _getAllBlocks. I find this code to be pretty self explanatory, I do admire the way zod’s Record schema validations are used on the auto generated registry index json.

Get free courses inspired by the best practices used in open source.

About me:

Website: https://ramunarasinga.com/

Linkedin: https://www.linkedin.com/in/ramu-narasinga-189361128/

Github: https://github.com/Ramu-Narasinga

Email: ramu.narasinga@gmail.com

Learn the best practices used in open source.

References:

  1. https://github.com/shadcn-ui/ui/blob/main/apps/www/app/(app)/blocks/page.tsx
  2. https://github.com/shadcn-ui/ui/blob/main/apps/www/lib/blocks.ts#L20
  3. https://github.com/shadcn-ui/ui/blob/main/apps/www/lib/blocks.ts#L75
  4. https://github.com/shadcn-ui/ui/blob/main/apps/www/registry/schema.ts#L16

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)