Open SalahAdDin opened 4 months ago
cc @valentinpalkovic
@SalahAdDin Have you followed the official documentation about setting up environment variables in Storybook?: https://storybook.js.org/docs/configure/environment-variables#using-storybook-configuration
@SalahAdDin Have you followed the official documentation about setting up environment variables in Storybook?: https://storybook.js.org/docs/configure/environment-variables#using-storybook-configuration
The thing is, if we are working with NextJS, it should not require extra configuration for environment variables.
Storybook isn't an integration into Next.js, but rather it runs as a separate App. Our APIs are mainly designed in a way to be usable across different kind of frameworks and renderers. Automatically loading your environment variables or even expose process.env to the browser automatically can be seriously dangerous. For sure, we could do whatever Next.js is doing behind the scenes to provide environment variables to the client and server bundle by following specific rules, but since an universal API to support envs already exists in Storybook and it is pretty trivial to set it up (usually did once), I don’t think we will support automatic detection of env vars for Next.js
@valentinpalkovic OK, I tried to mock some of the NextJS required environment variables as the documentation says:
env: (config) => ({
...config,
NEXT_PUBLIC_API_PORT: "6006",
}),
But it always returns undefined, and it is problematic.
Even this does not work:
Additional context
We are using Storybook as a workaround to test the pages with MSW, using the respective addon.
It could be fixed by applying this on the addon.
I have not tried the solution mentioned in the issue. With recent Storybook main.js/ts file, it would look more like this now:
import type { StorybookConfig } from '@storybook/nextjs';
import webpack from 'webpack';
const config: StorybookConfig = {
// All of your existing Storybook config
webpackFinal: async (config) => {
if (!config?.plugins) {
return config;
}
config.plugins.push(
new webpack.DefinePlugin(
Object.keys(process.env)
.filter((key) => key.startsWith('NEXT_PUBLIC_'))
.reduce(
(state, nextKey) => ({ ...state, [nextKey]: process.env[nextKey] }),
{},
),
),
);
return config;
},
};
export default config;
I have not tried the solution mentioned in the issue. With recent Storybook main.js/ts file, it would look more like this now:
import type { StorybookConfig } from '@storybook/nextjs'; import webpack from 'webpack'; const config: StorybookConfig = { // All of your existing Storybook config webpackFinal: async (config) => { if (!config?.plugins) { return config; } config.plugins.push( new webpack.DefinePlugin( Object.keys(process.env) .filter((key) => key.startsWith('NEXT_PUBLIC_')) .reduce( (state, nextKey) => ({ ...state, [nextKey]: process.env[nextKey] }), {}, ), ), ); return config; }, }; export default config;
Does it work?
One of my colleague just tested and this works:
webpackFinal: async (config: Configuration) => {
config.plugins = config.plugins || [];
config.plugins.push(
new DefinePlugin(
Object.keys(process.env)
.filter((key) => key.startsWith('NEXT_PUBLIC_'))
.reduce(
(acc, key) => ({
...acc,
[`process.env.${key}`]: JSON.stringify(process.env[key]),
}),
{}
)
)
);
return config;
},
One of my colleague just tested and this works:
webpackFinal: async (config: Configuration) => { config.plugins = config.plugins || []; config.plugins.push( new DefinePlugin( Object.keys(process.env) .filter((key) => key.startsWith('NEXT_PUBLIC_')) .reduce( (acc, key) => ({ ...acc, [`process.env.${key}`]: JSON.stringify(process.env[key]), }), {} ) ) ); return config; },
How do you manage the types? Where is the DefinePlugin
type?
@valentinpalkovic I think this is something we can support easily in @storybook/next
and we might as well to reduce friction for users. WDYT?
@SalahAdDin Here are the imports for TypeScript and the code:
import type { StorybookConfig } from '@storybook/nextjs';
import { Configuration } from 'webpack';
const { DefinePlugin } = require('webpack');
const config: StorybookConfig = {
// The rest of your configuration goes here...
// Needed to add this so that the NEXT_PUBLIC_ env variables are available in Storybook
webpackFinal: async (config: Configuration) => {
config.plugins = config.plugins || [];
config.plugins.push(
new DefinePlugin(
Object.keys(process.env)
.filter((key) => key.startsWith('NEXT_PUBLIC_'))
.reduce(
(acc, key) => ({
...acc,
[`process.env.${key}`]: JSON.stringify(process.env[key]),
}),
{}
)
)
);
return config;
},
};
export default config;
const { DefinePlugin } = require('webpack');
It requires to install the Webpack types from DefinitelyTyped, right?
I do not know where 'webpack' comes from as it is not in your package.json
dependencies. It must be a dependency of Storybook. For me, webpack is located at /myproject/node_modules/webpack/types
I also guess this import code would work just as fine: import { Configuration, DefinePlugin } from 'webpack';
I do not know where 'webpack' comes from as it is not in your
package.json
dependencies. It must be a dependency of Storybook. For me, webpack is located at/myproject/node_modules/webpack/types
I also guess this import code would work just as fine:import { Configuration, DefinePlugin } from 'webpack';
We are getting this issue. @jflheureux @shilman
Describe the bug
We use the environment variables to set up among others, API url, base url, etc. But when launching the storybook it is unable to find the setup environment variables!
To Reproduce
Just setup and NextJS project with storybook, define any page or function to use with environment variables, create its story and run it.
System
Additional context
We are using Storybook as a workaround to test the pages with MSW, using the respective addon.
It could be fixed by applying this on the addon.