@page-speed/blocks
High-performance rendering runtime for @opensite/ui components with pre-compiled Tailwind CSS and tree-shakable architecture.
Features
- Performance-First: Optimized for minimal bundle size and maximum runtime performance
- Tree-Shakable: Granular exports allow importing only what you need
- Flexible Styling: Works with both pre-compiled CSS and runtime Tailwind
- Registry-Based: Extensible component registry for custom renderers
- TypeScript: Full type safety with comprehensive type definitions
- React 18+: Built for modern React with hooks and concurrent features
Installation
pnpm add @page-speed/blocks
npm install @page-speed/blocks
yarn add @page-speed/blocks
Peer Dependencies
pnpm add react react-dom @opensite/ui @page-speed/img @opensite/video @page-speed/pressable
Quick Start
import { BlocksRenderer } from "@page-speed/blocks";
import type { Block } from "@page-speed/blocks/types";
const blocks: Block[] = [
{
_id: "1",
_type: "Box",
styles: "p-4 bg-gray-100",
content: "Hello World",
},
];
function App() {
return <BlocksRenderer blocks={blocks} />;
}
Core Concepts
Block Structure
Blocks are the fundamental building units, compatible with Chai design payloads:
interface Block {
_id: string;
_type: string;
_parent?: string | null;
styles?: string;
content?: string;
}
Component Registry
The library uses a registry system to map block types to renderer functions:
import { registerBlockRenderer } from "@page-speed/blocks/registry";
registerBlockRenderer("MyComponent", ({ block, context }) => {
return <div className={block.styles}>{block.content}</div>;
});
Tree-Shakable Imports
Import only what you need for optimal bundle size:
import { BlocksRenderer } from "@page-speed/blocks/core/renderer";
import { registerBlockRenderer } from "@page-speed/blocks/registry";
import type { Block } from "@page-speed/blocks/types";
import { BlocksRenderer } from "@page-speed/blocks/core";
import { registerBlockRenderer } from "@page-speed/blocks/registry";
import { BlocksRenderer, registerBlockRenderer } from "@page-speed/blocks";
API Reference
Components
BlocksRenderer
Main rendering component that processes block trees.
interface BlocksRendererProps {
blocks: Block[];
className?: string;
wrapper?: React.ComponentType<{ children: React.ReactNode }>;
}
Example:
<BlocksRenderer
blocks={blocks}
className="custom-wrapper"
wrapper={CustomWrapperComponent}
/>
Registry Functions
registerBlockRenderer(type, renderer)
Register a custom renderer for a block type.
registerBlockRenderer("CustomBlock", ({ block, context }) => {
return <div>{block.content}</div>;
});
getBlockRenderer(type)
Get a registered renderer by type.
const renderer = getBlockRenderer("CustomBlock");
hasBlockRenderer(type)
Check if a renderer is registered.
if (hasBlockRenderer("CustomBlock")) {
}
registerRenderers(renderers)
Batch register multiple renderers.
registerRenderers({
Header: ({ block }) => <header>{block.content}</header>,
Footer: ({ block }) => <footer>{block.content}</footer>,
});
Utility Functions
getRootBlocks(blocks)
Get all root-level blocks (blocks with no parent).
getChildBlocks(blocks, parentId)
Get all child blocks of a specific parent.
buildElementProps(block)
Build React props from block configuration (handles styles, attrs, etc.).
parseDesignPayload(payload)
Parse a design payload from string or object format.
Integration with @opensite/ui
This library is designed to work seamlessly with @opensite/ui components:
import { registerBlockRenderer } from "@page-speed/blocks";
import { Button } from "@opensite/ui/blocks/button/button-primary";
registerBlockRenderer("ButtonPrimary", ({ block, context }) => {
return (
<Button
href={block.link?.href}
className={block.styles}
>
{block.content}
{context.renderChildren(block._id)}
</Button>
);
});
Advanced Usage
Custom Wrapper Component
function CustomWrapper({ children }: { children: React.ReactNode }) {
return <div className="page-container">{children}</div>;
}
<BlocksRenderer blocks={blocks} wrapper={CustomWrapper} />
Error Handling
The renderer includes built-in error boundaries that catch rendering errors and display fallback UI:
Generic Renderer
For blocks without custom renderers, the library uses a generic renderer that maps block types to HTML elements:
import { genericBlockRenderer } from "@page-speed/blocks/core/renderer";
Performance Optimization
Pre-compiled CSS
For maximum performance, pre-compile your Tailwind CSS:
- Extract all
styles from your blocks
- Run Tailwind CLI to generate minimal CSS
- Serve the compiled CSS file
- Blocks will use the pre-compiled classes
Tree Shaking
Import from specific paths to enable tree shaking:
import { BlocksRenderer } from "@page-speed/blocks/core/renderer";
import { BlocksRenderer } from "@page-speed/blocks";
TypeScript Support
Full TypeScript support with comprehensive type definitions:
import type {
Block,
BlockRenderer,
BlockRenderContext,
DesignPayload
} from "@page-speed/blocks/types";
Browser Support
- Modern browsers (Chrome, Firefox, Safari, Edge)
- React 17+ (React 18+ recommended)
- ES2022+ features
License
BSD-3-Clause
Contributing
See CONTRIBUTING.md
Support