Using fonts in Storybook for Next.JS and Tailwind Projects
Tags: nextjs, tailwindcss, storybook, shadcnui
Published: 2024-02-29 21:53:48

I'm pretty new to Storybook. I am so frustrated I haven't used it in projects earlier as developing components in isolation is incredible. However I hit a bit of a gotcha this week when using it in my shadcn/ui based Next/Tailwind project.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y368k6o6p6ct12qhwdl1.png)

If you want to use a custom font in Next app router you need to [import them the next way](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to get the benefit of all Next's nextiness. If you're using Tailwind, [the Next docs instruct you](https://nextjs.org/docs/app/building-your-application/optimizing/fonts#with-tailwind-css) to export a variable name from the Next font object and insert it into the `classNames` of the body element in your root layout. You then reference this variable in your tailwind config under `sans` or your own chosen selector. This is also the instructions provided in [the shadcn/ui Next setup docs](https://ui.shadcn.com/docs/installation/next). As someone who doesn't really use CSS variables this seems incredibly arkane, but it works fantastically well.

However, I noticed that it wasn't **always** working. I don't want to admit how long it took me to simply realising that when I was working in Storybook the font wasn't loading. In fact the only thing that flagged this issue was that it was falling back to a default sans-serif system font which didn't have a full range of font weights. Long story short, my fonts were not in Storybook.

![Storybook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bcnhngpxh8hr7f7c3t9s.png)

Of course Storybook is **NOT** Next. The root layout where you are importing your font and defining its CSS variable isn't in use. Forehead slapping aside, the solution was relatively easy. In my case, I am using the shadcn/ui default font of [Inter](https://fonts.google.com/specimen/Inter) so I just needed to load this in and apply it to the body of the Storybook instance. And of course, you load this in, as per Google's advice, in the header of the document.

[A little digging into the Storybook docs reveals a useful feature](https://storybook.js.org/docs/api/main-config-preview-head) of `preview-head.html`, which is a file you can define in your `.storybook` directory which will then be treated as the head element of Storybook. This gives you somewhere to import your font from Google Font's CDN and also define a style tag where you apply the font to the body element. My file ended up looking like this:

```html
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet" />
<style>
    body {
        font-family: "Inter", sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
    }
</style>
```

A previous attempt at solving this involved importing the font at Storybook's `preview.tsx` in a global decorator, however this doesn't catch instances where components are instantiated as siblings of your story, such as with popovers or alert dialogs. A wrapper is almost as good, but using the preview head is more universal.

I hope this helps someone else in this confusing but not all that uncommon situation solve the problem a little faster than I did.