Roman Jelínek
Roman Jelínek

Reputation: 61

Next-translate to storybook

I´m looking for way to load static texts into storybook via next-translate.

My code looks like this, but it´s loading my locale files, but not writing them properly.

This is storybook preview.js:

import '../src/styles/global/global.scss';

import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/core/styles';
import theme from '../src/utils/theme';
import I18nProvider from 'next-translate/I18nProvider';

import commonCS from '../locales/cs/common.json';

export const decorators = [(Story) => themeDecorator(Story)];

const themeDecorator = (Story) => {
    console.log(commonCS.homepage_title);
    return (
        <ThemeProvider theme={theme}>
            <CssBaseline />
            <I18nProvider lang={'cs-CS'} namespaces={{ commonCS }}>
                <Story />
            </I18nProvider>
        </ThemeProvider>
    );
};

export const parameters = {
    actions: { argTypesRegex: '^on[A-Z].*' },
    controls: { expanded: true },
};

And this is my storybook storie:

import React from 'react';
import HeaderContact from './HeaderContact';
import I18nProvider from 'next-translate/I18nProvider';
import useTranslation from 'next-translate/useTranslation';
import commonCS from '../../../locales/cs/common.json';

export default {
    title: 'HeaderContact',
    component: HeaderContact,
};

export const Basic = () => {
    const { t } = useTranslation('common');
    return (
        <HeaderContact
            link="mailto:[email protected]"
            text={t('homepage_title')}
        />
    );
};

My local file common.json:

{
    "homepage_title": "Blog in Next.js",
    "homepage_description": "This example shows a multilingual blog built in Next.js with next-translate"
}

And my translate config i18n.json

{
    "locales": ["cs", "en", "de"],
    "defaultLocale": "cs",
    "pages": {
        "*": ["common"]
    }
}

I would be very glad for some help. Thanks! Roman

Upvotes: 1

Views: 1842

Answers (2)

Eduardo Gil Calvo
Eduardo Gil Calvo

Reputation: 1

This worked for me: I added this configuration in the preview.js

import I18nProvider from 'next-translate/I18nProvider';
import i18n from '../i18n.json';

async function getJSON(path) {
  const file = await fetch(path);
  return file.json();
}

async function fetchCommon(locale) {
  return await getJSON(`/${locale ?? i18n.defaultLocale}/common.json`);
}

const i18nDecorator = (Story, context) => {
  const { locale } = context.globals;
  const [common, setCommon] = useState({});

  useEffect(() => {
    fetchCommon(locale).then((data) => {
      setCommon(data);
    });
  }, [locale]);

  return (
    <Suspense fallback={<div>loading translations...</div>}>
      <I18nProvider lang={locale} namespaces={{ common }}>
        <Story {...context} />
      </I18nProvider>
    </Suspense>
  );
};

export const decorators = [i18nDecorator];

export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'en', title: 'English' },
        { value: 'es', title: 'Español' },
      ],
      showName: true,
    },
  },
};

In the main config you have to add the locales folder to the static dirs:

staticDirs: ['../locales'],

This is an example components

import useTranslation from 'next-translate/useTranslation';




export const ExampleI18n = () => {
  const { t } = useTranslation('common');

  return <div className={className}>{t('welcome-next')}</div>;
};

ExampleI18n.displayName = 'ExampleI18n';


Upvotes: 0

Roman Jel&#237;nek
Roman Jel&#237;nek

Reputation: 61

Here is the solution.

preview.js

import '../src/styles/global/global.scss';

import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/core/styles';
import theme from '../src/utils/theme';
import I18nProvider from 'next-translate/I18nProvider';

import commonCS from '../locales/cs/common.json';

export const decorators = [(Story) => themeDecorator(Story)];

const themeDecorator = (Story) => {
    console.log(commonCS.homepage_title);
    return (
        <ThemeProvider theme={theme}>
            <CssBaseline />
            <I18nProvider lang={'cs'} namespaces={{ common: commonCS }}>
                <Story />
            </I18nProvider>
        </ThemeProvider>
    );
};

export const parameters = {
    actions: { argTypesRegex: '^on[A-Z].*' },
    controls: { expanded: true },
};

Storie:

import React from 'react';

import HeaderContact from './HeaderContact';

export default {
    title: 'HeaderContact',
    component: HeaderContact,
};

export const Basic = () => {
    return <HeaderContact link="mailto:[email protected]" />;
};

Component:

import React from 'react';
import AlternateEmailIcon from '@material-ui/icons/AlternateEmail';
import useTranslation from 'next-translate/useTranslation';

import styles from './HeaderContact.module.scss';

export interface IHeaderContact {
    link: string;
    text?: string;
}

export default function HeaderContact(props: IHeaderContact) {
    const { link, text } = props;
    const { t } = useTranslation('common');
    const preklad = t('homepage_title');

    return (
        <a href={link} className={styles.headerLink}>
            <AlternateEmailIcon fontSize="small" />
            <span>
                {/* {text} */}
                {preklad}
            </span>
        </a>
    );
}

Upvotes: 5

Related Questions