Histoire, like so many other tools in the Vue ecosystem, is a bit of a neglected younger sibling to Storybook — a little bit uglier, with worse documentation and a couple rough edges, but much more tightly integrated with Vue and Vite. [1]

One thing that was not particularly obvious with using Histoire was how to declare a global variable. (There are a number of global variables Buttondown uses, but here's a common example: we drop Stripe's public client ID in to the Vue app by vending it in the request.)

Histoire doesn't document this, but the solution is pretty easy:

  1. Vite lets you declare globals via the define namespace within vite.config.js.
  2. Histoire lets you add vite overrides specific for histoire within the histoire.vite namespace.

Combine these and you get the answer:

import { defineConfig } from "vite";

import vue from "@vitejs/plugin-vue";

export default defineConfig({
  histoire: {
    vite: {
      define: {
        STRIPE_CLIENT_ID: 123,
      },
    },
  },

  // The rest of your vite config.
});

Hope this saves you ten minutes of Googling!


  1. I know Storybook 8 — released only a few days ago — purports to be better out of the box here, but in my brief time investigating this is not the case. Pulling in React and an entire slew of tools just for snapshotting was a bridge too far for me. ↩︎

Lightning bolt
About the author

I'm Justin Duke — a software engineer, writer, and founder. I currently work as the CEO of Buttondown, the best way to start and grow your newsletter, and as a partner at Third South Capital.

Lightning bolt
Greatest hits

Lightning bolt
Elsewhere

Lightning bolt
Don't miss the next essay

Get a monthly roundup of everything I've written: no ads, no nonsense.