How To Create a Carousel Component with Blocks as Children in Next.js (App Router) Using Builder.io Gen 2 SDK

Creating a Carousel Component with Blocks as Children in Next.js (App Router) Using Builder.io Gen 2 SDK

This guide demonstrates how to create a custom carousel component that allows blocks as children using the Builder.io Gen 2 SDK in a Next.js App Router project.

Prerequisites

Step 1: Set Up the Carousel Component

Create a file named Carousel.jsx inside your components directory. This component will render slides using the Builder.io component.

//jsx
"use client";
import React, { useState } from 'react';
import { Blocks } from '@builder.io/sdk-react';

export const Carousel = ({ slides, builderBlock }) => {
  const [currentSlide, setCurrentSlide] = useState(0);

  const nextSlide = () => {
    setCurrentSlide((prev) => (prev + 1) % slides.length);
  };

  const prevSlide = () => {
    setCurrentSlide((prev) => (prev - 1 + slides.length) % slides.length);
  };

  return (
    <div className="carousel">
      <button onClick={prevSlide}>Previous</button>
      <div className="carousel-slides">
        {slides ? slides.map((slide, index) => (
          <div
            key={index}
            style={{ display: index === currentSlide ? 'block' : 'none' }}
          >
            <Blocks
              parent={builderBlock.id}
              path={`component.options.slides.${index}.content`}
              blocks={slide.content}
            />
          </div>
        )) : ""}
      </div>
      <button onClick={nextSlide}>Next</button>
    </div>
  );
};

Step 2: Registering the Component with Builder.io

Create a file named builder-registry.ts in your project’s root directory to register the Carousel component.

//ts
import { type RegisteredComponent } from "@builder.io/sdk-react";
import { Carousel } from "./components/Carousel";

export const customComponents: RegisteredComponent[] = [
  {
    component: Carousel,
    name: 'Carousel',
    canHaveChildren: true,
    inputs: [
      {
        name: 'slides',
        type: 'list',
        subFields: [
          {
            name: 'content',
            type: 'uiBlocks',
            defaultValue: [],
          },
        ],
        defaultValue: [
          {
            content: [],
          },
        ],
      },
    ],
  },
];

Step 3: Fetching and Rendering Builder.io Content

Create a file named page.tsx inside your app directory to fetch the content and render it using the RenderBuilderContent component.

//ts
import { builder } from '@builder.io/sdk';
import { RenderBuilderContent } from '../../components/builder';
import { customComponents } from '../../builder-registry';

// Builder Public API Key set in .env file
builder.init(process.env.NEXT_PUBLIC_BUILDER_API_KEY);

interface PageProps {
  params: {
    page: string[];
  };
}

export default async function Page(props: PageProps) {
  const builderModelName = 'page';

  const content = await builder
    .get(builderModelName, {
      userAttributes: {
        urlPath: '/' + (props?.params?.page?.join('/') || ''),
      },
    })
    .toPromise();

  return (
    <>
      <RenderBuilderContent customComponents={customComponents} content={content} model={builderModelName} />
    </>
  );
}

Step 4: Creating the RenderBuilderContent Component

Create a file named builder.tsx to render Builder content with custom components.

//tsx
'use client';
import { Content, isPreviewing } from '@builder.io/sdk-react';
import '../builder-registry';

export function RenderBuilderContent({ content, model, customComponents }) {
  if (content || isPreviewing()) {
    return <Content customComponents={customComponents} content={content} model={model} apiKey={process.env.NEXT_PUBLIC_BUILDER_API_KEY} />;
  }

  return <div style={{ fontSize: '100px' }}>404 Not Found</div>;
}

Step 5: Configure Environment Variables

Ensure you have your Builder.io Public API Key set in your .env file as:
NEXT_PUBLIC_BUILDER_API_KEY=your-public-api-key

Conclusion

You have now set up a carousel component that supports blocks as children using Builder.io’s Gen 2 SDK within a Next.js App Router application. This allows you to dynamically render and manage slides within the Builder.io visual editor.
For more details, visit the Builder.io documentation.