Skip to content

Latest commit

 

History

58 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Crystallize React components

Typed React components for rendering Crystallize content: Image, Video, Grid, and Content Transformer.

Installation

Use your favorite package manager:

# pnpm
pnpm add @crystallize/reactjs-components

# npm
npm install @crystallize/reactjs-components

# yarn
yarn add @crystallize/reactjs-components

All components are exported from the package root and ship with TypeScript types.

import { Image, Video, GridRenderer, GridRenderingType, ContentTransformer } from '@crystallize/reactjs-components';

Image

Responsive wrapped in a with srcset support. Pass the image object you get from Crystallize.

import { Image } from '@crystallize/reactjs-components';

const imageFromCrystallize = {
    url: 'https://media.crystallize.com/.../image.jpg',
    altText: 'A nice product',
    variants: [
        // ImageVariant[] from @crystallize/schema
        { url: '.../image@400.jpg', width: 400 },
        { url: '.../image@700.jpg', width: 700 },
        { url: '.../image@1000.webp', width: 1000 },
    ],
};

export function ProductImage() {
    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

Video

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';

const videoFromCrystallize = {
    playlists: ['https://media.crystallize.com/.../master.m3u8', 'https://media.crystallize.com/.../stream.mpd'],
    thumbnails: [
        {
            url: 'https://media.crystallize.com/.../thumb.jpg',
            variants: [{ url: '.../thumb@700.jpg', width: 700 }],
        },
    ],
};

export function HeroVideo() {
    return (
        <Video
            {...videoFromCrystallize}
            autoPlay
            muted
            controls
            className="hero-video"
            videoProps={{ playsInline: true }}
        />
    );
}

Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/video

Grid

Render Crystallize grids in React using CSS Grid (default), a semantic table, or row/col wrappers.

Fetch the grid via GraphQL (minimum shape shown):

query grid($id: Int!, $language: String!) {
    grid(id: $id, language: $language) {
        rows {
            columns {
                layout {
                    rowspan
                    colspan
                    colIndex
                    rowIndex
                }
                item {
                    name
                }
            }
        }
    }
}

Render

import { GridRenderer, GridRenderingType } from '@crystallize/reactjs-components';

const Cell = ({ cell }: { cell: any }) => <div>{cell.item?.name}</div>;

<>
    {/* CSS Grid */}
    <GridRenderer grid={grid} type={GridRenderingType.Div} cellComponent={Cell} />

    {/* Table */}
    <GridRenderer grid={grid} type={GridRenderingType.Table} cellComponent={Cell} />

    {/* Row/Col wrappers */}
    <GridRenderer grid={grid} type={GridRenderingType.RowCol} cellComponent={Cell} />
</>;

Customize per cell via a render-prop or styleForCell

<GridRenderer grid={grid} type={GridRenderingType.Div} cellComponent={Cell}>
    {({ cells }) =>
        cells.map((cell) => (
            <div
                key={`${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

Content Transformer

Render Crystallize rich text JSON to React elements with optional per-node overrides.

import { ContentTransformer, NodeContent, type Overrides, type NodeProps } from '@crystallize/reactjs-components';

const overrides: Overrides = {
    link: (props: NodeProps) => (
        <a href={props.metadata?.href} rel={props.metadata?.rel} target={props.metadata?.target}>
            <NodeContent {...props} />
        </a>
    ),
};

<ContentTransformer json={richTextJson} overrides={overrides} />;

Live demo: https://crystallizeapi.github.io/libraries/reactjs-components/content-transformer

Notes on SSR

  • Image, Grid, and Content Transformer are SSR-friendly.
  • Video must run on the client. In Next.js, put the usage in a Client Component.

License

MIT © Crystallize

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages