Integrate sections with different page model

Please fill out as many of the following questions as possible so we can help you promptly! If you don’t know how to answer or it does not apply, feel free to remove it or leave it blank.

Builder content link

Builder public api key
1d8ecee591ac4358befb8fe998100548

What are you trying to accomplish
I am attempting to integrate section into our custom page models. Here is one of our page model, call “integration-details”. Checking on the documentation here, I don’t see a way to add multiple models in . If anyone has suggestion, I would love to hear it. :pray:

The following is our page.tsx under route “integrations/[[slugs]]”:

import { notFound } from 'next/navigation';

import BuilderComponent from 'components/Builder';

import { getAllDetailPageModelSlugs, getPostData } from 'utils/builder/builderSdkFunctions';

import type { Metadata } from 'next';

import renderMetadata from '@/utils/builder/renderMetaData';

type Params = {
  params: {
    slug?: string[];
  };
  searchParams: Record<string, string>;
};

export const generateMetadata = async ({ params }: Params): Promise<Metadata> => {
  const slug = params?.slug && Array.isArray(params?.slug) ? `/integrations/${params.slug.join('/')}` : '/integrations';
  const seoData = await getPostData(slug, 'integration-detail', 'data.seo');

  return renderMetadata(slug, seoData?.data?.seo);
};

export const generateStaticParams = async () => {
  const allSlugs = await getAllDetailPageModelSlugs('integration-detail');
  const paths = allSlugs?.map(({ data }) => {
    const properSlug = data?.url?.replace('/integrations/', '');
    const slug = properSlug?.split('/');

    return {
      slug: properSlug === '/integrations' ? [] : slug,
    };
  });

  return paths;
};

const IntegrationDetailPage = async ({ params, searchParams }: Params) => {
  const slug = params?.slug && Array.isArray(params?.slug) ? `/integrations/${params.slug.join('/')}` : '/integrations';
  const pageDataPromise = getPostData(slug, 'integration-detail');
  const [pageData] = await Promise.all([pageDataPromise]);

  const isEditing = searchParams?.['__builder_editing__'] === 'true';

  if (!pageData && slug !== '/integrations' && process.env.NODE_ENV === 'production' && !isEditing) {
    return notFound();
  }

  return <BuilderComponent model="integration-detail" content={pageData} />;
};

export default IntegrationDetailPage;

Also, because the section does not have a “route”, so, in local environment, how do I preview the section in the Builder editor. See the Loom Video for reference.

Code stack you are integrating Builder with
NextJs

Integrating a section into your custom page models on a Next.js site using Builder.io can be done by leveraging both the page model and the section model effectively.

Your current setup uses a custom page model integration-detail, and you want to include a section model within this page model. Here’s how you can achieve this within your Next.js application:

Step-by-Step Guide:

  1. Create a Section Model:
    Before you can integrate sections, ensure you have created a section model in Builder.io. This could be any reusable piece of content (e.g., a banner, a testimonial section, etc.).

  2. Register the Section Model in Next.js:
    Make sure you register or retrieve content for your section model in your Next.js application.

  3. Integrate Section within Page Component:
    Combine the section and the page content within your component by leveraging the BuilderComponent for rendering.

Implementation Example:

Below is a revised version of your page component that includes rendering a section along with the main page content.

1. Fetch Section Data:

First, update your getPostData function to fetch both the main page content and section content.

import { notFound } from 'next/navigation';
import BuilderComponent from 'components/Builder';
import { getAllDetailPageModelSlugs, getPostData } from 'utils/builder/builderSdkFunctions';
import type { Metadata } from 'next';
import renderMetadata from '@/utils/builder/renderMetaData';

type Params = {
  params: {
    slug?: string[];
  };
  searchParams: Record<string, string>;
};

export const generateMetadata = async ({ params }: Params): Promise<Metadata> => {
  const slug = params?.slug && Array.isArray(params?.slug)
    ? `/integrations/${params.slug.join('/')}`
    : '/integrations';
  const seoData = await getPostData(slug, 'integration-detail', 'data.seo');
  return renderMetadata(slug, seoData?.data?.seo);
};

export const generateStaticParams = async () => {
  const allSlugs = await getAllDetailPageModelSlugs('integration-detail');
  const paths = allSlugs?.map(({ data }) => {
    const properSlug = data?.url?.replace('/integrations/', '');
    const slug = properSlug?.split('/');
    return {
      slug: properSlug === '/integrations' ? [] : slug,
    };
  });
  return paths;
};

const IntegrationDetailPage = async ({ params, searchParams }: Params) => {
  const slug = params?.slug && Array.isArray(params?.slug)
    ? `/integrations/${params.slug.join('/')}`
    : '/integrations';

  // Fetch both the main page data and the section data
  const pageDataPromise = getPostData(slug, 'integration-detail');
  const sectionDataPromise = getPostData('/path-to-section', 'your-section-model');

  const [pageData, sectionData] = await Promise.all([pageDataPromise, sectionDataPromise]);

  const isEditing = searchParams?.['__builder_editing__'] === 'true';

  if (!pageData && slug !== '/integrations' && process.env.NODE_ENV === 'production' && !isEditing) {
    return notFound();
  }

  return (
    <>
      {/* Render the main page content */}
      <BuilderComponent model="integration-detail" content={pageData} />
      
      {/* Render the section */}
      <BuilderComponent model="your-section-model" content={sectionData} />
    </>
  );
};

export default IntegrationDetailPage;

2. Structuring Your Component Render:

Make sure you include both the BuilderComponent for the page model and the BuilderComponent for the section model within the return statement of your page.

return (
  <>
    {/* Render the main page content */}
    <BuilderComponent model="integration-detail" content={pageData} />
    
    {/* Render the section */}
    <BuilderComponent model="your-section-model" content={sectionData} />
  </>
);

Notes:

  • Section Content: Ensure that /path-to-section in getPostData('/path-to-section', 'your-section-model') is the correct path for fetching the section content.
  • Section Model: Replace 'your-section-model' with the actual name of your section model in Builder.io.
  • Component Customization: You can further customize how sections are laid out within the page as needed.

Additional Steps:

  1. Create Section Models in Builder.io:
    Go to your Builder.io Models section, and ensure you have created sections that you want to include in your custom page models.

  2. Integrate Dynamic Data:
    Optionally, you can inject dynamic data or use targeting features to customize sections based on specific user attributes or page contexts.

Documentation Links:

By following these steps, you should be able to effectively integrate sections within your custom page models and leverage the full flexibility of Builder.io in your Next.js application. If you need further assistance, feel free to reach out to Builder.io support or check the detailed documentation.