1

I have the next-i18next in my Next.js Project. And also add the storybook to my project.

When I try to add the story for the home page. I got error Module not found: Error: Can't resolve 'next-i18next/serverSideTranslations' in "xxxx\xxx\"

When I remove export const getStaticProps , the storybook works fine.

How to resolve this issue.

The following are my configurations

This is the translation in level 1 page.

import {serverSideTranslations} from 'next-i18next/serverSideTranslations'

export const getStaticProps = async ({locale}) => ({
  props: {
    ...await serverSideTranslations(locale, ['index']),
  },
})

.storybook/main.js

const path = require('path')

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    {
      name: 'storybook-addon-next',
      options: {
        nextConfigPath: path.resolve(__dirname, '../next.config.js')
      }
    }
  ],
  staticDirs: ['../public'],
  "framework": "@storybook/react",
  core: {
    builder: '@storybook/builder-webpack5'
  },
  webpackFinal: async (config, {configType}) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      "@": path.resolve(__dirname, "../src/"),
      'next-i18next': 'react-i18next'
    };
    config.resolve.modules = [path.resolve(__dirname, '..'), 'node_modules'];

    // this modifies the existing image rule to exclude .svg files
    // since we want to handle those files with @svgr/webpack
    const imageRule = config.module.rules.find(rule => rule.test.test('.svg'))
    imageRule.exclude = /\.svg$/

    // configure .svg files to be loaded with @svgr/webpack
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack']
    })

    // Return the altered config
    return config;
  },
  typescript: {
    check: true, // type-check stories during Storybook build
  }
}

.storybook/preview.js

//reset styles
import '../src/assets/styles/common.css'
import '../src/assets/styles/reset.css'
import '../src/assets/styles/other.scss'
//add antd style
import 'antd/dist/antd.css'
import React, {Suspense, useEffect} from "react";
import { initReactI18next, I18nextProvider } from 'react-i18next'
// import i18n from './i18n';
import i18next from 'i18next'
import * as NextImage from "next/image";
import { CUSTOM_VIEWPORTS } from './viewports'
import HttpApi from 'i18next-http-backend';

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$/,
    },
    expanded: true
  },
  viewport: {
    viewports: CUSTOM_VIEWPORTS,
  },
  storySort: {
    method: 'alphabetical',
    order: ['Common', 'Ant Design', 'Others'],
  },
}
// Create a global variable called locale in storybook
// and add a menu in the toolbar to change your locale
export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        {value: 'En', title: 'English'},
        {value: 'Fr', title: 'French'},
      ],
      showName: true,
    },
  },
};


// Wrap your stories in the I18nextProvider component
const i18nextStoryDecorator = (Story, context) => {
  const { locale } = context.globals;

  i18next
    .use(HttpApi)
    .use(initReactI18next)
    .init({
      whitelist:['En','Fr'],
      lng: locale,
      fallbackLng: 'En',
      ns: 'index',
      defaultNS: 'index',
      defaultLocale: "En",
      debug: true,
    })
  // When the locale global changes
  // Set the new locale in i18n
  useEffect(() => {
    i18next.changeLanguage(locale);
  }, [locale]);

  return (
    // here catches the suspense from components not yet ready (still loading translations)
    // alternative set useSuspense false on i18next.options.react when initializing i18next
    <Suspense fallback={<div>loading translations...</div>}>
      <I18nextProvider i18n={i18next}>
        <Story />
      </I18nextProvider>
    </Suspense>
  );
};

// export decorators for storybook to wrap your stories in
export const decorators = [i18nextStoryDecorator];
Xin Ning
  • 51
  • 6

0 Answers0