Published on

SwiperJS extra attributes from the server React/NextJS 14 issue

Recently, while integrating SwiperJS with NextJS 14, I encountered the “Warning: Extra attributes from the server: class, style” issue. This warning indicated a mismatch between the React virtual DOM and the actual DOM due to additional styles or classes added during page load.

warning

At the time, I was using Swiper JS version 11.0.5, and with Swiper planning to discontinue their React library, I decided to adopt the Swiper Element approach.

The issue stemmed from Swiper JS adding extra classes and styles to elements during rendering, causing a divergence between the virtual and actual DOM. Most probably because I was using React Suspense.

To address this, I implemented the dynamic import functionality in Next JS 14, disabling SSR (Server-Side Rendering). You can find details about dynamic import in the NextJS documentation.

Here’s a snippet from my code in MovieCategory.tsx:

import moviesApi from '@/lib/api/movies';
import CardSkeleton from '@/components/skeletons/card';
import { Suspense } from 'react';
import Link from 'next/link';
import dynamic from 'next/dynamic';

//Adding Import here
const DynamicSwiperCarousel = dynamic(
  () => import('../../swiper/swiper-carousel'),
  {
    ssr: false,
  }
);

export const MovieCategory = () => {
  const movies = moviesApi.getCategorized();

  return (
    <Suspense fallback={<CardSkeleton className="mt-16" />}>
      <MovieCards promise={movies} />
    </Suspense>
  );
};

/**
 * @todo TYPE define
 */
const MovieCards = async ({ promise }: any) => {
  const movies = await promise;

  return Object.entries(movies).map(([category, movies]: any) => {
    return (
      <>
        <DynamicSwiperCarousel data={movies} />
      </>
    );
  });
};

In this above code you can see line 8-13 – I am importing swiper-carousel using dynamic import and SSR has been set to false and on line 34 calling DynamicSwiperCarousel 

This way it should solve the warning for you. Hopefully this was helpful to you. Cheers!