Components
Register component in Shopstory config
Let's imagine the simplest possible component:
import React from "react";
export type CustomComponentProps = {
color: "white" | "purple" | "green",
noBorder: boolean
}
export const CustomComponent : React.FC<CustomComponentProps> = (props) => {
return <div style={{
border: props.noBorder ? "none" : "2px solid black",
background: props.color === "white" ? "white" : props.color === "green" ? "#83d1c4" : "#78517c",
padding: 24,
display: "flex",
justifyContent: "center",
alignItems: "center",
textAlign: "center"
}}>
My custom component
</div>
}
It displays a box with a border (that can be disabled with noBorder
prop) and with background (controlled by a background
prop).
To make it available in Shopstory the first thing we must do is to register it in the components
array of Shopstory configuration file:
export const shopstoryConfig: Config = {
// ...
components: [
{
id: "CustomComponent",
label: "Custom component",
schema: [
{
prop: "color",
label: "Color",
type: "select",
options: [
"white", "purple", "green"
]
},
{
prop: "noBorder",
label: "Disable border",
type: "boolean"
},
]
}
]
}
Each component must have a unique id
. schema
determines the properties that user can change in the Shopstory sidebar panel. Full reference of available field types available here.
Our component is already available in Shopstory but when you try to add it you will see a "Missing" error:

It's because Shopstory can't find the component instance.
Add component instance to ShopstoryProvider
ShopstoryProvider
The remaining step is to allow Shopstory find CustomComponent
instance. This task is handled by ShopstoryProvider
. Let's open src/shopstory/provider.tsx
file and add the component instance:
import { ShopstoryProvider } from "@shopstory/core/react";
import { CustomComponent } from "../components/CustomComponent/CustomComponent";
export const DemoShopstoryProvider : React.FC = ({ children }) => {
return <ShopstoryProvider
components={{
CustomComponent
}}
>
{ children }
</ShopstoryProvider>
}
DemoShopstoryProvider
must be added as a wrapper to all <ShopstoryCanvas />
and <Shopstory />
component calls. By doing that Shopstory will be able to access all custom component references and render them properly.
pages/shopstory-canvas.tsx
:
const ShopstoryCanvasPage: NextPage = () => {
return <DemoShopstoryProvider>
<Canvas config={shopstoryConfig} />
</DemoShopstoryProvider>
}
/pages/shopstory-block/[entryId].tsx
:
const ShopstoryBlockPage: NextPage<ShopstoryBlockPageProps> = (props) => {
return <DemoShopstoryProvider>
<ShopstoryMetadataProvider meta={props.meta}>
<Shopstory content={props.content} />
</ShopstoryMetadataProvider>
</DemoShopstoryProvider>
}
Voila! Let's see our component in action:
Component types
There are 3 component types in Shopstory.
item
(default) - available only in stacks inside of componentscard
- cards can be used in card grids or sliders.section
- full-screen section, can be added only at a root level of page
We haven't specified type
property for our CustomComponent
so it's treated as an item
.
If you want to change a type of custom component just set type
property in the component object:
export const shopstoryConfig: Config = {
// ...
components: [
{
id: "CustomComponent",
label: "Custom component",
type: "card"
schema: [
// ...
]
}
]
}
Now the custom component should be available in a card picker.
Layout compatibility
When Shopstory renders a custom component it's always wrapped with a container div
with display: grid
set. So the resulting markup looks kind of like this:
<div style={{display: "grid"}}>
<YourCustomComponent />
</div>
You should assume that the container div
might vary in size (it's controlled by Shopstory layout, not you). Thanks to the display: grid
your component will always fill the container div
. It's your job to make your component adapt properly to different widths and heights. However, in most cases you don't need to do much.
Next steps
Connecting 3rd party resources (like products from e-commerce platforms, CMS entries, assets, etc) to component properties
Last updated