Configuring Storybook 8 with Gatsby can be a little tricky. Here is what you need to do.
Make sure your main.ts file looks like this:
import type { StorybookConfig } from '@storybook/react-webpack5';
import { Configuration, RuleSetRule } from 'webpack';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
import path from 'path';
const config: StorybookConfig = {
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
framework: '@storybook/react-webpack5',
stories: ['../**/*.stories.@(js|jsx|mjs|ts|tsx)'],
webpackFinal: async (config: Configuration) => {
// Custom rule for ts files
const tsRule: RuleSetRule = {
test: /\.(tsx?|jsx?)$/,
loader: 'ts-loader',
options: {
transpileOnly: true
}
};
if (config.module?.rules) {
// Make whatever fine-grained changes you need
config.module.rules.push({
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../')
});
}
// tsconfig paths
if (config.resolve) {
config.resolve.plugins = [
...(config.resolve.plugins || []),
new TsconfigPathsPlugin({
extensions: config.resolve.extensions
})
];
}
return {
...config,
module: {
...config.module,
rules: [...(config.module?.rules || []), tsRule]
}
};
}
};
export default config;
Then use your preview.ts file to import any styles, as well as Gatsby's suggestions.
import { action } from "@storybook/addon-actions"
// Import your scss
import '@/scss/my-app.scss';
// Gatsby's Link overrides:
// Gatsby Link calls the `enqueue` & `hovering` methods on the global variable ___loader.
// This global object isn't set in storybook context, requiring you to override it to empty functions (no-op),
// so Gatsby Link doesn't throw errors.
global.___loader = {
enqueue: () => {},
hovering: () => {},
}
// This global variable prevents the "__BASE_PATH__ is not defined" error inside Storybook.
global.__BASE_PATH__ = "/"
// Navigating through a gatsby app using gatsby-link or any other gatsby component will use the `___navigate` method.
// In Storybook, it makes more sense to log an action than doing an actual navigate. Check out the actions addon docs for more info: https://storybook.js.org/docs/react/essentials/actions
window.___navigate = pathname => {
action("NavigateTo:")(pathname)
}