Search code examples
next.jsstorybook

Storybook Cannot read properties of undefined (reading 'name') error with nextjs


Trying to get storybook working with nextjs but getting this error.

TypeError: Cannot read properties of undefined (reading 'name') at http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:4049:37 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:18699:12 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:18757:12 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:4094:20 at unboundStoryFn (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:18398:12) at renderWithHooks (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:89911:18) at mountIndeterminateComponent (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:93675:13) at beginWork (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:95188:16) at beginWork$1 (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:101027:14) at performUnitOfWork (http://localhost:6006/vendors-node_modules_storybook_addon-actions_preview_js-generated-config-entry_js-node_module-16c9e3.iframe.bundle.js:100161:12)

// main.js

const path = require('path');

module.exports = {
  stories: [
    // '../stories/**/*.stories.mdx',
    // '../stories/**/*.stories.@(js|jsx|ts|tsx)',
    '../**/*.stories.mdx',
    '../**/*.stories.@(js|jsx|ts|tsx)',
  ],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/preset-scss',
    '@storybook/addon-interactions',
  ],
  framework: '@storybook/react',
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader?url=false', 'sass-loader'],
        include: path.resolve(__dirname, '../'),
      },

      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  core: {
    builder: '@storybook/builder-webpack5',
  },
  webpackFinal: async (config) => {
    return {
      ...config,
      resolve: {
        ...config.resolve,

        alias: {
          ...config.resolve.alias,
          '@': path.resolve(__dirname, '../'),
        },
      },
    };
  },
};

// preview.js

import * as NextImage from 'next/image';
import '../styles/globals.scss';
import { RouterContext } from 'next/dist/shared/lib/router-context';
import { withNextRouter } from 'storybook-addon-next-router';

const BREAKPOINTS_INT = {
  xs: 375,
  sm: 600,
  md: 900,
  lg: 1200,
  xl: 1536,
};

const customViewports = Object.fromEntries(
  Object.entries(BREAKPOINTS_INT).map(([key, val], idx) => {
    console.log(val);
    return [
      key,
      {
        name: key,
        styles: {
          width: `${val}px`,
          height: `${(idx + 5) * 10}vh`,
        },
      },
    ];
  })
);

// Allow Storybook to handle Next's <Image> component
const OriginalNextImage = NextImage.default;

Object.defineProperty(NextImage, 'default', {
  configurable: true,
  value: (props) => <OriginalNextImage {...props} unoptimized />,
});

export const decorators = [withNextRouter];

export const parameters = {
  actions: { argTypesRegex: '^on[A-Z].*' },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
  nextRouter: {
    Provider: RouterContext.Provider,
  },
  viewport: { viewports: customViewports },
};

sorry for dumping whole config here.

found this on google search but I don't even have @storybook/addon-a11y addon https://github.com/storybookjs/storybook/issues/10803


Solution

  • Solved the issue and I think the problem was with the @storybook/preset-scss. This is the working main.js and preview.js respectively:

    const path = require('path');
    
    module.exports = {
      stories: [
        '../stories/welcome.stories.tsx',
        '../stories/**/*.stories.mdx',
        '../stories/**/*.stories.@(js|jsx|ts|tsx)',
        '../**/*.stories.mdx',
        '../**/*.stories.@(js|jsx|ts|tsx)',
      ],
      addons: [
        '@storybook/addon-essentials',
        '@storybook/addon-links',
        // '@storybook/addon-actions',
        'storybook-addon-next-router',
        'storybook-addon-next',
        '@storybook/addon-interactions',
        // '@storybook/preset-scss',
      ],
      framework: '@storybook/react',
      module: {
        rules: [
          {
            test: /\.scss$/,
            use: ['style-loader', 'css-loader', 'sass-loader'],
            include: path.resolve(__dirname, '../'),
          },
          {
            test: /\.css$/,
            use: ['style-loader', 'css-loader'],
            include: path.resolve(__dirname, '../'),
          },
    
          {
            test: /\.tsx?$/,
            use: 'ts-loader',
            exclude: /node_modules/,
          },
        ],
      },
    
      core: {
        builder: '@storybook/builder-webpack5',
      },
      webpackFinal: async (config) => {
        return {
          ...config,
          resolve: {
            ...config.resolve,
    
            alias: {
              ...config.resolve.alias,
              '@': path.resolve(__dirname, '../'),
            },
          },
        };
      },
    };
    
    
    import * as NextImage from 'next/image';
    // import '../styles/globals.scss';
    import '!style-loader!css-loader!sass-loader!../styles/globals.scss';
    
    import { RouterContext } from 'next/dist/shared/lib/router-context'; // next 12
    
    const BREAKPOINTS_INT = {
      xs: 375,
      sm: 600,
      md: 900,
      lg: 1200,
      xl: 1536,
    };
    
    const customViewports = Object.fromEntries(
      Object.entries(BREAKPOINTS_INT).map(([key, val], idx) => {
        console.log(val);
        return [
          key,
          {
            name: key,
            styles: {
              width: `${val}px`,
              height: `${(idx + 5) * 10}vh`,
            },
          },
        ];
      })
    );
    
    // Allow Storybook to handle Next's <Image> component
    const OriginalNextImage = NextImage.default;
    
    Object.defineProperty(NextImage, 'default', {
      configurable: true,
      value: (props) => <OriginalNextImage {...props} unoptimized />,
    });
    
    export const parameters = {
      actions: { argTypesRegex: '^on[A-Z].*' },
      controls: {
        matchers: {
          color: /(background|color)$/i,
          date: /Date$/,
        },
      },
      nextRouter: {
        Provider: RouterContext.Provider,
        // foo: 'this-is-a-global-override',
      },
      viewport: { viewports: customViewports },
    };