javascriptdynamicnext.jsdynamic-import

How can I dynamically import in a NextJs page data (array) not entire component


Hi all I followed the next tutorial https://nextjs.org/docs/advanced-features/dynamic-import and works great for components

But I need to fetch data dynamically. Situation:

I have one simple component named MyItems that receives as props items which is a list of elements title, category.

I want to dynamically import these lists from typescript files stored in page-data/myitems/de|en.ts and so on

So these ts files export array after doing some calculations that is why i don't import json dynamically or search for other solution. I need them to have code and export an array export default [{name: 'somename', title: somemagic()]

I have this page in pages/page

const Page = async ({ t, ...props }: Props) => {
    const locale = props._nextI18Next.initialLocale;
 

    const items = (await import(`../page-data/myitems/${locale}`)).default;
    console.log(items); // HERE I SEE OUTPUT FINE

    return (
        <>
            <Head>
                <title>dynamic test</title>
            </Head>
            {/*@ts-ignore*/}
            <MyPage items={items} />
        </>
    );
};

The error I get is that cannot return promise to react So my understanding is that I cannot export async component.

Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

That is all fine, so my question is howcan I solve this situation then ?

The goal is still the same (items are fetched fine now but the component is returned as promise due to async and rest of react magic fails)


Solution

  • I have solved this issue myself and am posting the solution for anyone facing the same issue.

    So summarized You still import dynamically one react component, but the "localized" react component relies on the common page. For example page-en.tsx imports page.tsx (see below)

    This will be your NextJs main page:

    import React from 'react';
    
    import dynamic from 'next/dynamic';
    
    const Page = ({ t, ...props }: Props) => {
        const locale = props._nextI18Next.initialLocale;
        const nt = scopedT(t, T_NAMESPACE);
    
        const DynamicComponent = dynamic(() => import(`../page-data/mypage/${locale}`));
    
        return (
            <>
                <Head>
                    <title>{nt('pageTitle')}</title>
                </Head>
                {/*@ts-ignore*/}
                <DynamicComponent />
            </>
        );
    };
    

    and this will be your page-data/mypage/en|de|whateverlang.tsx

    const En: React.FC = () => {
        return <MyPage items={getItemsForLocale('en')} />;
    };