简体   繁体   中英

Dynamically load components on a page in Next.js app

I have a Next.js Server Side Rendered app where I need to load components dynamically.

eg Homepage, I make an API call in getServerSideProps to fetch homepage data, which will consist of some basic information about the page along with names of all the components and data for each component. From here I need to render these components dynamically in the page body. And these dynamic components need to be rendred on the server for SEO.

Here is my simplified code

import Head from 'next/head';
import Header from '../components/Header';
import Banner from '../components/Banner';

import { getDomainFromContext, getParamFromContext } from '../src/utils';
import { fetchPage } from '../src/fetchers';

export async function getServerSideProps(context) {
    const domain = getDomainFromContext(context);
    const locale = getParamFromContext(context, 'locale');
    const uri = '/';

    const page = await fetchPage(domain, uri, locale);

    /*
        page now has names of the components with data for each component. e.g
        {
            ...
            components : {
                {
                    "name" : "Venues",
                    "data" : "..."
                },
                {
                    "name" : "Info",
                    "data" : "..."
                }
            }
            ...
        }
     */


    return {
        props: {
            domain: domain,
            locale: locale,
            page: page
        },
    };
}

function Home(props) {
    
    return (
        <>
            <Head>
                <title>Create Next App</title>
                <meta name="description" content="Generated by create next app" />
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <Header>
                <h1>Homepage</h1>
            </Header>

            <main>
                <Banner />
                {/*Load Dynamic components here & it should be server side rendered.*/}
            </main>
        </>
    );
}

export default Home;

So I based my solution on the answer in this question : Dynamic Importing of an unknown component - NextJs

I created a function that accepts component name to load, and once I have the component names from the API, I loop through component names to load & save them in an array, and save data in an array as well. Later components are rendered from the array.

import Head from 'next/head';
import Header from '../components/Header';
import { getDomainFromContext, getParamFromContext } from '../src/utils';
import { fetchPage } from '../src/fetchers';
import { Suspense } from 'react';


export function getDynamicComponent(c) {
    return dynamic(() => import(`../components/${c}`), {
        suspense: true,
    });
}

export async function getServerSideProps(context) {
    let domain = getDomainFromContext(context);
    let locale = getParamFromContext(context, 'locale');
    let pageUri = '/'


    const page = await fetchPage(companyId, pageUri);

    return {
        props: {
            domain: domain,
            locale: locale,
            page: page,
        },
    };
}

function Home(props) {
    
    let components = [];
    let componentsData = [];

    props.page.components.forEach((component, i) => {
        components.push(getDynamicComponent(component.name));
        componentsData.push(component.data);
    });

    return (
        <>
            <Head>
                <title>Create Next App</title>
                <meta name="description" content="Generated by create next app" />
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <Header>
                <h1>Homepage</h1>
            </Header>

            <main>
                <Suspense fallback={`...`}>
                    {components.map((Component, k) => (
                        <Component key={k} data={componentsData.data[k]} />
                    ))}
                </Suspense>
            </main>
        </>
    );
}

export default Home;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM