storybook-addon-i18n icon indicating copy to clipboard operation
storybook-addon-i18n copied to clipboard

Cannot read property 'toResolveHierarchy' of undefined

Open brettdewoody opened this issue 5 years ago • 4 comments

I'm using storybook-addon-i18n and have a conditional i18next configuration depending on an environment variable. In Storybook I bundle the translation files. In my actual web app I use the i18next-xhr-backend to load the translations from my server.

To do this I define a STORYBOOK_ env variable when running npm run storybook, and in the configuration of i18n conditionally use XHR, or import the translations as resources. Like this:

const locales = ['en', 'de']
const isDev = process.env.NODE_ENV !== 'production'
const useXHR = process.env.STORYBOOK_USE_I18N_XHR !== 'false'

const options = {
  debug: true,
  preload: ['en'],
  fallbackLng: 'en',
  interpolation: {
    escapeValue: false, // not needed for react as it escapes by default
  },
}

const loadTranslationFiles = async (options, useXHR, XHR, locales) => {
  // In the app we load translation files with XHR
  // In Storybook we bundle the translation files
  if (useXHR) {
    i18n.use(XHR)
    const backend = {
      loadPath: '/locales/{{lng}}/{{ns}}.json',
    }
    return {
      ...options,
      backend,
    }
  } else {
    // Load all the translation files using a dynamic import
    return await Promise.all(locales.map((locale) => import(`../../public/locales/${locale}/translation.json`))).then(
      ([...translations]) => {
        const resources = translations.reduce((result, translation, idx) => {
          result[locales[idx]] = { translation: translation.default }
          return result
        }, {})

        return {
          ...options,
          resources,
        }
      },
    )
  }
}

const optionsWithLngs = await loadTranslationFiles(options, useXHR, XHR, locales)

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(optionsWithLngs)

This works until I refresh Storybook. When I do it throws the following error:

Cannot read property 'toResolveHierarchy' of undefined
TypeError: Cannot read property 'toResolveHierarchy' of undefined
    at setLng (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:91445:62)
    at I18n.changeLanguage (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:91462:9)
    at http://localhost:9002/main.86a2811ac76424356127.bundle.js:318:14
    at commitHookEffectList (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:130174:26)
    at commitPassiveHookEffects (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:130198:3)
    at HTMLUnknownElement.callCallback (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:113040:14)
    at Object.invokeGuardedCallbackDev (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:113090:16)
    at invokeGuardedCallback (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:113147:31)
    at commitPassiveEffects (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:131665:9)
    at wrapped (http://localhost:9002/vendors~main.86a2811ac76424356127.bundle.js:143892:34)

If I switch to a different story everything starts working again.

I see some items in the changelog related to fixing this issue of toResolveHierarchy returning undefined, but on much earlier versions if i18n.

Package versions "i18next": "^19.0.0", "i18next-browser-languagedetector": "^4.0.1", "i18next-xhr-backend": "^3.2.2", "react-i18next": "^11.0.1", "storybook-addon-i18n": "^5.1.11", "@storybook/react": "^5.2.5",

brettdewoody avatar Nov 09 '19 01:11 brettdewoody

@brettdewoody storybook-addon-i18n is library agnostic. It means that it doesn't depend on any particular localization library. As you can see in our package.json we don't have any i18n dependencies. So the problem is most likely resides in your .storybook/config.js, particularly in addParameters({ i18n: {...} }).
If you could share your config I may be able to help.

alexeychikk avatar Nov 10 '19 14:11 alexeychikk

I am also seeing this, but I'm using react-i18next client side.

    "i18next": "^19.0.3",
    "react-i18next": "^11.3.1",
    "@storybook/core": "^5.3.14",
    "@storybook/react": "^5.3.14",
    "storybook-addon-i18n": "^5.1.13",

I'm also using the new config files not the old config.js: https://medium.com/storybookjs/declarative-storybook-configuration-49912f77b78

ldeveber avatar Mar 03 '20 20:03 ldeveber

I am also seeing this, but I'm using react-i18next client side.

    "i18next": "^19.0.3",
    "react-i18next": "^11.3.1",
    "@storybook/core": "^5.3.14",
    "@storybook/react": "^5.3.14",
    "storybook-addon-i18n": "^5.1.13",

I'm also using the new config files not the old config.js: https://medium.com/storybookjs/declarative-storybook-configuration-49912f77b78

...just kidding. I got it working client side, see below:

preview.js:

import { addParameters, addDecorator } from '@storybook/react';
import { withI18n } from 'storybook-addon-i18n';
import i18n from '../src/i18n';
import { I18nextProvider } from 'react-i18next';

addParameters({
  i18n: {
    provider: I18nProviderWrapper,
    providerProps: {
      i18n
    },
    supportedLocales: [ 'en' ],
  },
});

addDecorator(withI18n);

../src/i18n:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import * as en from './locales/en'; // these are the translated files

i18n.use(initReactI18next).init({
  // for all options read: https://www.i18next.com/overview/configuration-options
  fallbackLng: 'en',
  languages: [ 'en' ],
  debug: false,

  lng: 'en',
  returnObjectTrees: true,
  interpolation: {
    escapeValue: false, // not needed for react as it escapes by default
  },
  resources: {
    en,
  },
});

export default i18n;

ldeveber avatar Mar 03 '20 20:03 ldeveber

@ldeveber Thanks for your reply. From your preview.js it's not clear what is I18nProviderWrapper. Could you please share the code of it so that others could benefit from your solution?

alexeychikk avatar Mar 04 '20 09:03 alexeychikk