@shopkit/builder
v0.1.2
Published
Page builder for creating dynamic storefronts with configurable widgets and layouts
Maintainers
Readme
@shopkit/builder
Configuration-driven page builder for creating dynamic storefronts with widgets and layouts.
Features
- Configuration-Driven: Define pages with JSON configuration (PageConfig)
- Widget System: Modular, reusable widget components
- Data Sources: Automatic data fetching from commerce backends
- Responsive Design: Built-in breakpoint system for responsive layouts
- Theme Integration: Seamless integration with
@shopkit/coretheme system - SSR Support: Full server-side rendering compatibility with Next.js
Installation
npm install @shopkit/builder
# or
bun add @shopkit/builderPeer Dependencies
npm install react react-dom nextQuick Start
import { createPageBuilder, WidgetRegistry, DATA_SOURCE_TYPES } from '@shopkit/builder';
// 1. Create widget registry
const widgetRegistry = new WidgetRegistry();
widgetRegistry.register('hero', HeroWidget);
widgetRegistry.register('product-grid', ProductGridWidget);
// 2. Create page builder
const pageBuilder = createPageBuilder({
widgets: widgetRegistry,
commerceClient: myShopifyClient,
themeLoader: myThemeLoader,
templateLoader: myTemplateLoader,
});
// 3. Render a page
const content = await pageBuilder.renderPage({
merchantName: 'my-store',
routeContext: { templateName: 'home', path: '/' },
});Core Concepts
PageConfig
The central configuration object that defines a page's structure:
import type { PageConfig, SectionConfig, WidgetConfig } from '@shopkit/builder';
const homePageConfig: PageConfig = {
id: 'home',
name: 'Home Page',
dataSources: {
featuredProducts: {
type: DATA_SOURCE_TYPES.PRODUCTS,
params: { first: 8 },
required: true,
},
},
sections: [
{
id: 'hero-section',
name: 'Hero',
settings: { layout: 'full', padding: { top: '0', bottom: '0' } },
widgets: [
{
id: 'hero-1',
type: 'hero',
settings: {
title: 'Welcome to Our Store',
subtitle: 'Discover amazing products',
ctaText: 'Shop Now',
ctaLink: '/collections/all',
},
},
],
},
{
id: 'products-section',
name: 'Featured Products',
settings: { layout: 'page' },
widgets: [
{
id: 'products-1',
type: 'product-grid',
dataSourceKey: 'featuredProducts',
settings: { columns: 4 },
},
],
},
],
};Data Source Types
Built-in data source types for fetching commerce data:
import { DATA_SOURCE_TYPES } from '@shopkit/builder';
// Available types:
DATA_SOURCE_TYPES.PRODUCT // Single product by handle/ID
DATA_SOURCE_TYPES.PRODUCTS // Multiple products with pagination
DATA_SOURCE_TYPES.PRODUCTS_BY_HANDLES // Products by specific handles
DATA_SOURCE_TYPES.COLLECTION // Single collection
DATA_SOURCE_TYPES.COLLECTIONS // Multiple collections
DATA_SOURCE_TYPES.COLLECTION_PAGE_WITH_FILTERS // Collection with faceted filters
DATA_SOURCE_TYPES.PRODUCT_RECOMMENDATIONS // Product recommendations
DATA_SOURCE_TYPES.STATIC // Static data (no fetching)Widget Registry
Register widgets for use in page configurations:
import { WidgetRegistry } from '@shopkit/builder';
const registry = new WidgetRegistry();
// Register a widget
registry.register('product-card', ProductCardWidget);
// Check if widget exists
registry.has('product-card'); // true
// Get a widget
const Widget = registry.get('product-card');Interfaces
The builder uses dependency injection. Implement these interfaces for your commerce platform:
ICommerceClient
import type { ICommerceClient } from '@shopkit/builder';
const shopifyClient: ICommerceClient = {
getProduct: async (handle) => { /* ... */ },
getProducts: async (params) => { /* ... */ },
getCollection: async (handle) => { /* ... */ },
getCollections: async (params) => { /* ... */ },
// ...
};IThemeLoader
import type { IThemeLoader } from '@shopkit/builder';
const themeLoader: IThemeLoader = {
loadTheme: async (merchantName, role) => { /* ... */ },
};ITemplateLoader
import type { ITemplateLoader } from '@shopkit/builder';
const templateLoader: ITemplateLoader = {
loadTemplate: async (merchantName, templateName) => { /* ... */ },
listTemplates: async (merchantName) => { /* ... */ },
};Presets
Use presets for common configurations:
File System Preset
import { createFileSystemPageBuilder } from '@shopkit/builder';
const pageBuilder = await createFileSystemPageBuilder({
basePath: './src/themes',
widgets: myWidgetRegistry,
commerceClient: myCommerceClient,
});Subpath Exports
// Main exports
import { createPageBuilder, PageConfig, WidgetRegistry } from '@shopkit/builder';
// React hooks
import { usePageBuilder } from '@shopkit/builder/hooks';Type Reference
PageConfig
interface PageConfig {
id: string;
name: string;
dataSources?: Record<string, DataSourceConfig>;
sections: SectionConfig[];
}SectionConfig
interface SectionConfig {
id: string;
name: string;
settings: SectionSettings;
widgets: WidgetConfig[];
}WidgetConfig
interface WidgetConfig {
id: string;
type: string;
settings: Record<string, unknown>;
dataSourceKey?: string;
responsive?: WidgetResponsiveConfig;
}DataSourceConfig
interface DataSourceConfig {
type: DataSourceType | string;
params: Record<string, any>;
required: boolean;
}Layout Options
Built-in layout constants:
import {
SECTION_TYPES,
SECTION_LAYOUT_OPTIONS,
SECTION_ALIGNMENT_OPTIONS,
ASPECT_RATIO_OPTIONS,
TEXT_ALIGNMENT_OPTIONS,
CARD_STYLE_OPTIONS,
} from '@shopkit/builder';Responsive Breakpoints
Default breakpoints for responsive design:
import { DEFAULT_BREAKPOINTS } from '@shopkit/builder';
// { sm: 640, md: 768, lg: 1024, xl: 1280, '2xl': 1536 }Integration with @shopkit/core
The builder integrates seamlessly with the theme system:
import { createPageBuilder } from '@shopkit/builder';
import { createThemeRegistry } from '@shopkit/core/theme';
const themeRegistry = createThemeRegistry({
basePath: './src/themes',
});
const pageBuilder = createPageBuilder({
widgets: widgetRegistry,
commerceClient: shopifyClient,
themeLoader: themeRegistry,
templateLoader: templateLoader,
});License
MIT
