In this article, we’ll cover how to leverage React and JSX to write components for Storybook for HTML. We also provide reasons for why anyone would ever want to do such a thing. A working knowledge of Storybook and React is assumed.

new Year(); new You(): 5 DEG UI Resolutions for 2020

A bit of background

Before we dive in, let’s provide some context. At DEG, our front-end web development team works on projects of varying size and complexity, including web applications, content-driven marketing sites, headless content management system (CMS) platforms, and landing pages.

While many of these projects are developed with front-end libraries and frameworks, such as React, others are more content-driven with moderate interactive functionality. For the latter, we often forego frameworks in favor of a more traditional approach: HTML delivered by the server with a vanilla JavaScript layer where necessary.

Put simply, we want to use the right tools for the job at hand. Or, if you prefer, not everything needs to be a React app.

Storybooking

For traditional HTML websites, our team has used Pattern Lab for years as a component-driven development tool. We build our site elements as Mustache templates, compile and test them locally in Pattern Lab, and then export them to their final destination (often a CMS platform).

Pattern Lab has worked well for us. However, we are not immune to the allurements of Storybook and its ever-growing community.

Our team had recently migrated to Storybook for React to build components for React application, so we were already familiar with its benefits. It wasn’t long before we pondered using Storybook to build components for our traditional HTML websites.

We were initially skeptical of Storybook for HTML. At first glance, one thing that immediately stood out was the repetitive nature of generating a component’s HTML for stories. For example, the code for two stories about a button might look something like this:

As you can see, we have to duplicate the button’s HTML for each story. On a small scale, this is annoying. On a large scale, it is time consuming and not maintainable.

HTML templating engines are a good way to combat code duplication. We eventually came across examples of developers incorporating templating engines such as Handlebars into their component stories. Storybook for HTML was beginning to look like a viable option.

We then had to choose an HTML templating engine. One of our resolutions for 2020 was to move away from Mustache. It has served us well over the years, but we aren’t fans of its syntax and limited logic capabilities.

Then, in a brief moment of clarity, we realized that React provides a friendly syntax (JSX) and powerful, familiar logic capabilities (javaScript itself) for rendering component HTML. React is a full-blown user interact library. But, if you look at it from another angle, it can be a capable HTML templating engine, as well.

React templating

Using VirtualBox to Test IE11 on a Mac

An idea was taking shape: write React components to generate HTML that we could feed into our Storybook for HTML stories.

But hold on. If we’re writing React components, why wouldn’t we just use Storybook for React? A reasonable question, and one that we have revisited on several occasions. The answer involves a component’s client-slide JavaScript.

In our traditional HTML websites, some components require JavaScript to layer on additional functionality. An example is a button that opens a modal dialog. Ideally, we want to see a component’s JavaScript functionality in action within Storybook. We don’t want to see React lurking on the client side, interfacing with the document object modal (DOM) and our JavaScript layer.

In short, we should avoid mixing vanilla (non-React) JavaScript and React JavaScript on a component at runtime in the browser. Storybook for HTML renders a component as plain HTML without any client-side React.

With that question answered, we could focus on a proof of concept for our idea. A simple React-templated component to use within Storybook might look like this:

We’ve converted our button example from earlier into a React component. The stories for that button now look like this:

We’re importing our button React component and using it within each of our stories. Hooray, code duplication averted.

So far, so good. Our next step is to prevent Storybook for HTML from choking on our React components.

Decorating

Storybook for HTML expects each story function to return one of the following:

  • HTML string
  • HTML DOM element

Our stories are currently returning a React component. To make Storybook for HTML happy, we need a way to convert our React component into HTML.

As it so happens, the “react-dom” package offers a simple method for transforming React components into static HTML: renderToStaticMarkup. This function accepts a React element as a parameter and returns an HTML string. On a side note, a similar technique is used for React-based, server-side rendering frameworks.

Armed with the “renderToStaticMarkup” function, we can create a simple Storybook decorator. Decorations allow us to intercept and modify stories before they are rendered. Ours looks like this:

This decorator accepts a story function, executes it, and passes the returned value (a React component) to the “renderToStaticMarkup” function. The resulting HTML string is returned from the decorator.

Assuming that this decorator lives within a “.storybook/decorators/renderToStaticMarkup.js” file, we can then apply it globally to all stories within Storybook’s “preview.js” file:

Don’t forget to install the “react” and “react-dom” packages into your project.

Odds and ends

And we’re done! Well, almost.

If you try to build Storybook at this point, you will likely encounter compilation errors in your story files. This is because we have JSX syntax in our components and stories, and Storybook for HTML doesn’t understand that syntax out of the box.

Storybook runs on Webpack and offers a way to modify its Webpack configuration. I won’t get into the sticky details of configuring Webpack here. Briefly, we need to install Babel’s preset-react package and add it to Storybook’s presets for bundling JavaScript files. Create a “.storybook/webpack.config.js” file and add the following code to it:

This will allow Storybook’s Webpack to understand and compile JSX syntax.

Keep your React components dumb

We are leveraging React components purely as a build-time static HTML generator for our components within Storybook. The HTML for these components will eventually reside within a website that likely will not include React.

JSS or SXA: Choosing the Best Sitecore Approach

Final thoughts

Our team is still experimenting with this approach of using React as an HTML templating engine within Storybook, but we have been cautiously optimistic so far. JavaScript and JSX are a powerful combination. We’re interested to learn if other developers are using React in this way and how they are implementing Storybook for HTML at scale.

Keep in touch.

Stay up-to-date on the latest digital trends, DEG news, and upcoming events by subscribing to DEG's newsletter.

Subscribe

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comments

  • Kevin Lorenz

    Kevin Lorenz

    2 months
    Reply
    Heyho thanks for this article. We're looking at the almost exact same problem and this is helping a lot. Any way we could have a look at the code of your storybook setup?
  • Kevin Lorenz

    Kevin Lorenz

    2 months
    Reply
    Nice article, thanks a lot. Did you also look into using the docs addon and how to render your static code in their code block?