It's possible to add custom coded buttons to Shopstory. Custom buttons are a special kind of custom components. The differences from standard components are:

  1. You can connect actions to the buttons.

  2. Buttons can be used as links.

  3. Only buttons can be added to button groups.

How to make my custom Button compatible with Shoptory?

Custom Button is compatible with Shopstory when it satisfies following conditions.

It understands as property

The custom buttons will be compatible with Shopstory only when they properly interpret as property. There are 3 possible values for as:

  1. as="button" - you must display your button as a semantic <button>.

  2. as="a" - you must display your button as <a> (so it's not a button in a semantic meaning, only visual)

  3. as=undefined - no action connected to button. You should leave it as <button> or <div>.

Pass onClick, href, target, etc.

All standard a or button properties like onClick, href, target, etc must be passed to the underlying DOM button or a elements.

Understands label property

Custom buttons have a built-in label property.


Below you can see a properly defined custom coded Shopstory button:

import React from "react";
import { ShopstoryButton } from "@shopstory/core/types";
import css from "./Button.module.css";

export type ButtonProps = {
  variant: "dark" | "light" | "dark-outline" | "light-outline"

export const Button : ShopstoryButton<ButtonProps> = (props) => {
  const { as, variant, ...restProps } = props;

  let extraClass = "";
  if (variant === "light") {
    extraClass = css["Button--light"];
  } else if (variant === "dark-outline") {
    extraClass = css["Button--outline"];
  } else if (variant === "light-outline") {
    extraClass = css["Button--light-outline"]

  return React.createElement(as ?? "div", { ...restProps, className: `${css.Button} ${extraClass}` }, props.label)

We register buttons in the config using buttons property:

export const shopstoryConfig: Config = {
    // ...
  buttons: [
      id: "Button",
      label: "Demo Button",
      schema: [
          prop: "variant",
          label: "Variant",
          type: "select",
          options: [
            "dark", "light", "dark-outline", "light-outline"

As with components, we must pass the component instance to ShopstoryProvider :

import { ShopstoryProvider } from "@shopstory/core/react";
import { CustomComponent } from "../components/CustomComponent/CustomComponent";
import {Button} from "../components/Button/Button";

export const DemoShopstoryProvider : React.FC = ({ children }) => {
  return <ShopstoryProvider
    { children }

Let's see our button in action:

Last updated