Typed React components for rendering Crystallize content: Image, Video, Grid, and Content Transformer.
Use your favorite package manager:
# pnpm pnpm add @crystallize/reactjs-components # npm npm install @crystallize/reactjs-components # yarn yarn add @crystallize/reactjs-componentsAll components are exported from the package root and ship with TypeScript types.
import{Image,Video,GridRenderer,GridRenderingType,ContentTransformer}from'@crystallize/reactjs-components';Responsive wrapped in a
import{Image}from'@crystallize/reactjs-components';constimageFromCrystallize={url: 'https://media.crystallize.com/.../image.jpg',altText: 'A nice product',variants: [// ImageVariant[] from @crystallize/schema{url: '.../[email protected]',width: 400},{url: '.../[email protected]',width: 700},{url: '.../[email protected]',width: 1000},],};exportfunctionProductImage(){return<Image{...imageFromCrystallize}sizes="(max-width: 600px) 90vw, 700px"className="product-image"/>;}Notes
- If the API returns caption in json/html/plainText, the component renders it as .
- You can provide width/height to avoid layout shift; otherwise the largest variant's dimensions are used when available.
Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/image
Progressive video player that prefers HLS (m3u8) and falls back to MPEG-DASH (mpd). Renders a thumbnail and a play button, then hydrates the player.
Important
- This component is client-side only (it contains 'use client'). In Next.js, place it in a client component.
- Include the provided styles once in your app:
import'@crystallize/reactjs-components/assets/video/styles.css';Usage
import{Video}from'@crystallize/reactjs-components';constvideoFromCrystallize={playlists: ['https://media.crystallize.com/.../master.m3u8','https://media.crystallize.com/.../stream.mpd'],thumbnails: [{url: 'https://media.crystallize.com/.../thumb.jpg',variants: [{url: '.../[email protected]',width: 700}],},],};exportfunctionHeroVideo(){return(<Video{...videoFromCrystallize}autoPlaymutedcontrolsclassName="hero-video"videoProps={{playsInline: true}}/>);}Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/video
Render Crystallize grids in React using CSS Grid (default), a semantic table, or row/col wrappers.
Fetch the grid via GraphQL (minimum shape shown):
querygrid($id: Int!, $language: String!){grid(id: $id, language: $language){rows{columns{layout{rowspancolspancolIndexrowIndex } item{name } } } } }Render
import{GridRenderer,GridRenderingType}from'@crystallize/reactjs-components';constCell=({ cell }: {cell: any})=><div>{cell.item?.name}</div>;<>{/* CSS Grid */}<GridRenderergrid={grid}type={GridRenderingType.Div}cellComponent={Cell}/>{/* Table */}<GridRenderergrid={grid}type={GridRenderingType.Table}cellComponent={Cell}/>{/* Row/Col wrappers */}<GridRenderergrid={grid}type={GridRenderingType.RowCol}cellComponent={Cell}/></>;Customize per cell via a render-prop or styleForCell
<GridRenderergrid={grid}type={GridRenderingType.Div}cellComponent={Cell}>{({ cells })=>cells.map((cell)=>(<divkey={`${cell.layout.rowIndex}-${cell.layout.colIndex}`}style={{gridColumn: `span ${cell.layout.colspan}`,gridRow: `span ${cell.layout.rowspan}`}}>{cell.item.name}</div>))}</GridRenderer>Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/grid
Render Crystallize rich text JSON to React elements with optional per-node overrides.
import{ContentTransformer,NodeContent,typeOverrides,typeNodeProps}from'@crystallize/reactjs-components';constoverrides: Overrides={link: (props: NodeProps)=>(<ahref={props.metadata?.href}rel={props.metadata?.rel}target={props.metadata?.target}><NodeContent{...props}/></a>),};<ContentTransformerjson={richTextJson}overrides={overrides}/>;Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/content-transformer
- Image, Grid, and Content Transformer are SSR-friendly.
- Video must run on the client. In Next.js, put the usage in a Client Component.
MIT © Crystallize