How to display Basehub CMS data in a swiper carousel without server/client component conflicts?

I’m working on a frontend project where I need to fetch data from Basehub CMS and display it in a carousel slider. However, I’m running into issues with mixing server and client components in the same file.

When I try to separate the carousel items into their own component, the swiper only shows the first item and doesn’t work properly. I think there’s a conflict between how Basehub handles data fetching and how Swiper.js needs to render the slides.

const Portfolio = async () => {
  return (
    <Query
      requests={[
        {
          __typename: true,
          portfolio: {
            entries: {
              title: true,
              content: {
                text: true,
              },
              featuredImage: { src: true, width: true, height: true, description: true },
            },
          },
        },
      ]}
    >
      {async ([result]) => {
        'use server';

        if (!result.portfolio.entries.length) {
          return <div>No portfolio items available</div>;
        }

        const portfolioItems = result.portfolio.entries;

        return (
          <div className='flex flex-col min-h-screen h-[400px]'>
            <Navigation />
            <Carousel className='flex-1 relative carousel-container'>
              <div className='flex h-full w-full'>
                {portfolioItems.map((item, idx) => (
                  <div
                    className='h-full w-full flex carousel-item'
                    key={idx}
                  >
                    <div className='flex-1 bg-gray-50 p-6 flex items-center justify-center'>
                      <img
                        src={item.featuredImage?.src as string}
                        alt={item.featuredImage?.description as string}
                        width='auto'
                        height='100%'
                      />
                    </div>
                    <div className='p-8 w-[400px] flex flex-col justify-start gap-6'>
                      <h3 className='text-xl font-semibold'>{item.title}</h3>
                      <p>{item.content?.text}</p>
                    </div>
                  </div>
                ))}
              </div>
            </Carousel>
          </div>
        );
      }}
    </Query>
  );
};

Has anyone successfully integrated Basehub CMS data with Swiper carousel? What’s the best approach to handle this server/client component mixing issue?

This happens because Basehub’s server-side rendering clashes with Swiper’s client-side setup. I ran into the same thing and fixed it with a data bridge pattern. Pull your Basehub query into a separate server component that just fetches data, then pass that portfolio data as props to a client component with your Swiper code. Make sure you mark the Swiper component with ‘use client’ and feed it data through props instead of trying to fetch directly. This way you keep Basehub’s server-side benefits while letting Swiper initialize properly on the client with full carousel functionality.

Nice setup! Try using useEffect to initialize swiper after your data loads - the carousel often breaks when it mounts before slides are ready. Are you seeing any hydration errors in console? Those usually point to what’s causing the server/client mismatch.

i faced the same probs too. honestly, just make sure swiper’s wrapped in a client comp. try passing portfolioItems from your server comp to it. that’s fixed it for me when splitin the data fetch part from the carousel stuff.