Shopify’s Hydrogen framework has been an exciting addition to the headless landscape. Since its release a few short months ago, the framework has matured quickly, responding to feedback from developers and merchants alike. But if you’re a developer and you’ve been working with front-end frameworks, mainly component-based ones, for a while, you’ll quickly ask yourself, “Where is an example of this being used with Storybook?” – We’ve got you covered. We’re giving you a developer’s step-by-step guide to using Storybook with Hydrogen.
Note: This article is specifically geared towards Hydrogen developers and explores how brands can use Storybook with Shopify’s Hydrogen framework. For those in a hurry and want to explore a working example, please find our demo repo here.
Like Hydrogen, Storybook has transformed in the last few months. Concentrating on developer experience and modern tooling, the release of Storybook 6.5 gave us Interaction testing, Figma Plugin, Faster Webpack, and the Vite builder.
Vite is the development server and bundle engine that powers more and more development projects. It’s at the heart of Shopify’s Hydrogen framework powering the development experiences and SSR rendering on Shopify’s edge network.
So with this engine now being natively supported by Storybook, you’d expect getting this set up would be easy. Let’s test that theory with a demo store - with this in place, it should be as simple as yarn dev to see a test store.
1. Let’s start by creating a Hydrogen demo store
2. Choose a template
3. Choose Typescript
4. Name your store
Now we have the demo store, let’s go ahead and install Storybook with a Vite builder. Storybook has concentrated on developer experience, so this process can be started with a single command.
Storybook will automatically detect the presence of React and go ahead and add the relevant dependencies.
You will also be promoted to run the ESLint migration, which we advise you do.
Now we should be able to go ahead and run Storybook with yarn storybook.
Well… that didn’t work out so good, did it?
Unfortunately, this throws an error, but it’s quickly resolved. The core of this error is Vite itself. With builder-vite v0.2.0 upward, Storybooks builder depends on Vite 3.x while, at the time of writing, Hydrogen still uses Vite 2.x.
So the fix is simple enough, pin the builder to the last version that supported Vite 2.x v0.1.41. Open your package.json file and amend @storybook/builder-vite to use v0.1.41.
Run yarn install, and let’s try yarn storybook again. Everything runs as it should this time, and, as a result, Storybook will launch.
So, with a little bit of dependency pinning, it’s possible to run Storybook inside the Hydrogen Vite config. However, soon this step won’t be necessary as Hydrogen moves to Vite 3.0.
Hydrogen inside Storybook?
Storybook is useful to have alongside your project. But its real utility is breaking your UI into components that can be previewed, tested, and composed outside your application. So let’s try importing an existing Hydrogen component - ProductCard.client.tsx seems like a good candidate.
We need to create a new story file alongside the existing component, ProductCard.stories.tsx. Let’s look at the basic layout of the file…
Once our basic story is importing ComponentStory and ComponentMeta for Storybook and our ProductCard component from the existing component file. We then simply declare our new story. In this example, we’ve declared our title to match the path to the component file itself. Now we can go ahead and declare our template to output our component.
But, before we rerun Storybook, we need to set some default data for our component. We do this by binding a template to our component.
To create a default set, we suggest using React Dev tools to capture the props from the demo store.
You may find that typescript complains about some of these types. That itself isn’t a great concern here, but we should note that Hydrogen still has some fairly basic problems with its typing of objects like images.
Now we have a component and some default data, let’s try accessing our component inside Storybook.
So at a basic level, it looks like our import isn’t supported
At a basic level, it looks like our import isn’t supported. This first error is actually related to our use of typescript. The terminal output will show you that the ‘~/’ import path has not been recognized.
Storybook has a plugin to help resolve this issue, allowing it to import the project TSconfig.
We can then amend our .storybook/main.js to use this plugin and understand our import paths.
With this in place, let’s try again.
So at a basic level, it looks like our import isn’t supported
We’ve hit our next roadblock. Hydrogens components use components like <Link> that will be assumed to run inside wider app-wide contexts like <Router>. If we import the router and wrap it around this component, the router itself will fail. Because it, too, depends on HOC and data passed during Hydrogen build.
But we’re not ending things there.
It’s very common in frameworks to use Global decorators to stub HOCs on which framework components depend. If you’ve worked with React Router or Next.js, you are likely familiar with the process.
Some 3 hours after its release, Hydrogen 1.5.0 made their internal test provider <ShopifyTestProviders> publicly available via import {ShopifyTestProviders} from '@shopify/hydrogen/testing'. This should allow us to create a simple decorators file for use in our config. Inside the .storybook folder, we created the following decorators.tsx.
Updating our preview.js file to preivew.ts and adding the following:
By doing things this way, we can import and use a TSX component as a global decorator. To accompany our new global decorator, we have to make one last change to the Storybook main config file and add one additional package.
We need to add two variables to the Storybook config (.storybook/main.ts) that the ShopifyTestProviders HOC checks to enable its functionality.
Finally, we need to add an additional dev dependency to our package, used by our ShopifyTestProviders. Simply run yarn add faker@5.5.3 -D
If you’re still with us, you might gather there is a catch coming.
While 1.5.0 has made ShopifyTestProviders available for import, one of the individual test utilities imported by the provider currently depends on the faker library, but it does so without declaring dependency. This causes any component that imports ShopifyTestProviders to fail.
Note: Until our PR for a fix is merged, we have installed a patch to remove this undeclared dependency in this demonstration.
With everything in place, only one piece remains. To ensure that we use the same global styling as the main application, simply import the index style sheet into preview.ts.
With our new global decorator in place and styles configured, we are ready to once again run yarn story-book and finally, we can see our Hydrogen component output.
Please see our GitHub repo to check out the above example in code.
And for more examples of how we are working with headless in Shopify, check out our recent case study on how Pavers went headless with Shopify Plus and our in-depth guide to headless with Shopify.