How to run Remix <Link /> Component in Storybook

If you've encountered the error useHref() may be used only in the context of a <Router> component while trying to integrate Remix's <Link /> component into Storybook, fear not. In this guide, we'll walk through a solution that involves creating a decorator in the preview.tsx file of your Storybook setup using the createRemixStub utility.

The Problem:

One of the common challenges developers face when working with Remix and Storybook is the error message that suggests the use of useHref() is limited to the context of a <Router> component. This issue often arises when trying to render Remix components, especially <Link />, in the isolated environment of Storybook.

The error message might look something like this:

useHref() may be used only in the context of a <Router> component.

This error can be frustrating, especially when you're excited about integrating Remix into your Storybook workflow. Fortunately, there's a solution that involves creating a decorator to set up the necessary context for Remix components to function correctly.

The Solution: Creating a Decorator with createRemixStub

To overcome the aforementioned error and successfully run Remix <Link /> components in Storybook, we'll leverage the createRemixStub utility. This utility allows us to set up a minimal Remix environment within Storybook, providing the required context for components like <Link /> to work seamlessly.

Step 1: Install Dependencies

Make sure you have the necessary dependencies for testing in Remix installed in your project. If not, you can install them using npm or yarn:

npm install @remix-run/testing
# or
yarn add @remix-run/testing

Make sure to install the same version of @remix-run/react and @remix-run/testing!

Step 2: Create a Remix Stub in preview.tsx and use in a decorator

In your Storybook setup, locate the preview.tsx file. If it doesn't exist, create one in the .storybook directory. Add the following code to create a Remix stub:

import type {Preview} from '@storybook/react';
import {createRemixStub} from '@remix-run/testing';

const preview: Preview = {
  parameters: {
    // ...
  },
  decorators: [
    (Story) => {
      const RemixStub = createRemixStub([
        {
          path: '*',
          action: () => ({redirect: '/'}),
          loader: () => ({redirect: '/'}),
          Component: () => <Story />,
        },
      ]);

      return <RemixStub />;
    },
  ],
};

With these steps in place, you should now be able to run Remix <Link /> components in Storybook without encountering the previous error.