Links

Links are special kinds of components responsible for page transitions. Obviously you want your website to be accessible and crawlable by Google so all the links should display as <a href>.

Shopstory comes with a single built-in link action called "Basic Link". Basic Link has 2 parameters ("url" and "open in new window") and displays the link as standard <a> tag:

Custom routing

Basic Link might be OK for external links but in case of internal links most of the modern React frameworks (next, Gatsby) have their own custom routing strategy. Good news is that it's easy to connect any routing strategy to Shopstory.

Let's see the example. We'll create new link action called "Internal Link" and connect it to next/link. We start by adding a new link to the config:

export const shopstoryConfig: Config = {
  // ...
  links: [
    {
      id: 'NextLink',
      label: 'Internal link',
      schema: [
        {
          prop: 'pagePath',
          label: 'Path',
          type: 'string',
          defaultValue: '/'
        }
      ]
    }
  ],
}

As you can see it's very similar to custom actions, components, etc. However, in the ShopstoryProvider it becomes a bit different:

import { ShopstoryProvider, ShopstoryLink } from "@shopstory/core/react";
import Link from "next/link";

const NextLink : ShopstoryLink = ({ Component, componentProps, values }) => {
  return (
    <Link href={values.pagePath} passHref={true}>
      <Component {...componentProps} />
    </Link>
  )
}

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

Shopstory link must be compatible with ShopstoryLink type. It's a React component that takes 3 properties:

  • Component -> an instance of ShopstoryButton. It can be your custom button or a button built directly in Shopstory.

  • componentProps -> those are properties that you must pass to the Component. If you don't do it you'll break compatibility and Shopstory might behave in an unpredictable way.

  • values -> values populated by the editor in the sidebar

In order to stay compatible with Shopstory, custom ShopstoryLink must render Component with componentProps passed to it. <Component {...componentProps} /> always renders as an a component. Depending on your needs you might need to wrap it with another component (like next.js Link) or pass some extra properties to Component (like href or target).

It's very common to manage page URLs in a headless CMS. Usually a page URL is represented by a content type called URL, Page path, URL Route, etc. With Shopstory it's very easy to connect a link action to CMS entry. All you need to do is to provide user with a CMS entry field instead of a text field for URL. Contentful example:

export const shopstoryConfig: Config = {
  // ...
  links: [
    {
      id: 'NextLink',
      label: 'Internal link',
      schema: [
        {
          prop: 'url',
          label: 'URL',
          type: 'resource',
          resourceType: 'contentful-entry',
          params: {
            contentTypeId: ['URLRoute'] // name of your URL content type
          }
        }
      ]
    }
  ],
}

Your custom ShopstoryLink can access the URLRoute entry via values.url property.

Last updated