Douglas Henrique
Douglas Henrique

Reputation: 321

SwiperJS styling does not work with NextJS

I've installed SwiperJS into my NextJS project. I've following exactly the Swiper Tutorial Documentation but there's an issue when I try to styling classes like .swiper, .swiper-slide ... The styles are not responding to my custom styles.

In my case, my slider is a Component and there is a folder called Slider with index.tsx file and slider.module.scss.

My index.tsx:

import Image from 'next/image';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Navigation, Pagination, Scrollbar } from 'swiper';

import styles from './slider.module.scss'

import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';

export function SliderPortfolio() {
  return (
    <div className={styles.teste}>
      <Swiper
        className={styles.mySwiper}
        modules={[Navigation, Pagination, Scrollbar]}
        spaceBetween={50}
        slidesPerView={3}
        navigation
        pagination={{ clickable: true }}
        scrollbar={{ draggable: true }}
      >
        <SwiperSlide>
          <div className={styles.imageContainerNext}>
            <Image
              className={styles.imageNext}
              src={'/images/dribble-mockup.png'}
              alt="Illustration of a person carrying ideas for a professional website design"
              layout="fill"
            />
          </div>
        </SwiperSlide>
        <SwiperSlide>
          <div className={styles.imageContainerNext}>
            <Image
              className={styles.imageNext}
              src={'/images/dribble-mockup.png'}
              alt="Illustration of a person carrying ideas for a professional website design"
              layout="fill"
            />
          </div>
        </SwiperSlide>
        <SwiperSlide>
          <div className={styles.imageContainerNext}>
            <Image
              className={styles.imageNext}
              src={'/images/dribble-mockup.png'}
              alt="Illustration of a person carrying ideas for a professional website design"
              layout="fill"
            />
          </div>
        </SwiperSlide>
        <SwiperSlide>
          <div className={styles.imageContainerNext}>
            <Image
              className={styles.imageNext}
              src={'/images/dribble-mockup.png'}
              alt="Illustration of a person carrying ideas for a professional website design"
              layout="fill"
            />
          </div>
        </SwiperSlide>
      </Swiper>

    </div>

  )
}

My slider.module.scss:

.teste {
  background:  blue; //works

  .mySwiper {
    background: red; //works

    .swiper {
      background: yellow; // doesn't work
    }

    .swiper-slide {
      display: none; // doesn't work
    }

  }
}

What I'm missing?

Upvotes: 6

Views: 29511

Answers (6)

Gin
Gin

Reputation: 13

Ran into same problem, you just need to add "use client" on top of your file

Upvotes: 0

Rakesh Tiwari
Rakesh Tiwari

Reputation: 1

it work in yarn dev but when i make build it do not work
import 'swiper/css'; // also tried import "swiper/swiper.min.css";
export { Navigation, Thumbs, Pagination, Autoplay, Grid } from 'swiper';
export { Swiper, SwiperSlide } from 'swiper/react';
export type { SwiperOptions } from 'swiper';


import {
  Navigation,
  Swiper,
  SwiperOptions,
  SwiperSlide,
  Thumbs,
} from '@/components/ui/carousel/Sliders'
import { productGalleryPlaceholder } from '@/public/assets/placeholders'
import { getDirection } from '@/utils/getDirection'
import cn from 'classnames'
import { Attachment } from 'lib/types/products'
import Image from 'next/image'
import { useRouter } from 'next/router'
import { useRef, useState } from 'react'
import { IoIosArrowBack, IoIosArrowForward } from 'react-icons/io'
import Scrollbar from '../Scrollbar'

interface Props {
  gallery: Attachment[]
  thumbnailClassName?: string
  galleryClassName?: string
}

// product gallery breakpoints
const galleryCarouselBreakpoints = {
  '0': {
    slidesPerView: 4,
  },
}

const swiperParams: SwiperOptions = {
  slidesPerView: 1,
  spaceBetween: 0,
}

const ThumbnailCarousel: React.FC<Props> = ({
  gallery,
  thumbnailClassName = 'xl:w-[480px] 2xl:w-[650px]',
  // galleryClassName = 'xl:w-28 2xl:w-[130px]',
  galleryClassName,
}) => {
  const [thumbsSwiper, setThumbsSwiper] = useState<any>(null)
  const prevRef = useRef<HTMLDivElement>(null)
  const nextRef = useRef<HTMLDivElement>(null)
  const { locale } = useRouter()
  const dir = getDirection(locale)

  return (
    <div className="w-full xl:flex xl:flex-row-reverse">
      <div
        className={cn(
          'relative mb-2.5 w-full overflow-hidden rounded-md border border-border-base md:mb-3 xl:ltr:ml-5 xl:rtl:mr-5',
          thumbnailClassName
        )}
      >
        {!!thumbsSwiper ? (
          <Swiper
            id="productGallery"
            thumbs={{ swiper: thumbsSwiper }}
            modules={[Navigation, Thumbs]}
            navigation={{
              prevEl: prevRef.current!, // Assert non-null
              nextEl: nextRef.current!, // Assert non-null
            }}
            {...swiperParams}
          >
            {gallery?.map((item) => (
              <SwiperSlide
                key={`product-gallery-${item.id}`}
                className="flex items-center justify-center"
              >
                <Image
                  src={item?.original ?? productGalleryPlaceholder}
                  alt={`Product gallery ${item.id}`}
                  // width={650}
                  // height={590}
                  width={540}
                  height={440}
                  className="rounded-lg object-contain"
                />
              </SwiperSlide>
            ))}
          </Swiper>
        ) : (
          <Swiper
            id="productGallery"
            modules={[Navigation, Thumbs]}
            navigation={{
              prevEl: prevRef.current!, // Assert non-null
              nextEl: nextRef.current!, // Assert non-null
            }}
            {...swiperParams}
          >
            {gallery?.map((item) => (
              <SwiperSlide
                key={`product-gallery-${item.id}`}
                className="flex items-center justify-center"
              >
                <Image
                  src={item?.original ?? productGalleryPlaceholder}
                  alt={`Product gallery ${item.id}`}
                  width={540}
                  height={440}
                  className="rounded-lg object-contain"
                />
              </SwiperSlide>
            ))}
          </Swiper>
        )}
        <div className="absolute top-2/4 z-10 flex w-full items-center justify-between px-2.5">
          <div
            ref={prevRef}
            className="flex h-7 w-7 -translate-y-1/2 transform cursor-pointer items-center justify-center rounded-full bg-brand-light text-base shadow-navigation transition duration-300 hover:bg-brand hover:text-brand-light focus:outline-none md:h-8 md:w-8 lg:h-9 lg:w-9 lg:text-lg xl:h-10 xl:w-10 xl:text-xl"
          >
            {dir === 'rtl' ? <IoIosArrowForward /> : <IoIosArrowBack />}
          </div>
          <div
            ref={nextRef}
            className="flex h-7 w-7 -translate-y-1/2 transform cursor-pointer items-center justify-center rounded-full bg-brand-light text-base shadow-navigation transition duration-300 hover:bg-brand hover:text-brand-light focus:outline-none md:h-8 md:w-8 lg:h-9 lg:w-9 lg:text-lg xl:h-10 xl:w-10 xl:text-xl"
          >
            {dir === 'rtl' ? <IoIosArrowBack /> : <IoIosArrowForward />}
          </div>
        </div>
      </div>
      {/* End of product main slider */}

      <Scrollbar
        options={{
          overflow: { y: 'scroll' },
          scrollbars: {
            visibility: 'visible',
          },
        }}
      >
        <div className={`shrink-0 ${galleryClassName}`}>
          <Swiper
            id="productGalleryThumbs"
            modules={[Navigation, Thumbs]}
            onSwiper={setThumbsSwiper}
            spaceBetween={0}
            watchSlidesProgress
            freeMode
            observer
            observeParents
            breakpoints={galleryCarouselBreakpoints}
          >
            {gallery?.map((item) => (
              <SwiperSlide
                key={`product-thumb-gallery-${item.id}`}
                className="flex cursor-pointer items-center justify-center overflow-hidden rounded border border-border-base transition hover:opacity-75"
              >
                <Image
                  src={item?.thumbnail ?? productGalleryPlaceholder}
                  alt={`Product thumb gallery ${item.id}`}
                  // width={170}
                  // height={170}
                  width={70}
                  height={70}
                />
              </SwiperSlide>
            ))}
          </Swiper>
        </div>
      </Scrollbar>
    </div>
  )
}

export default ThumbnailCarousel

Upvotes: 0

saintyusuf
saintyusuf

Reputation: 504

I've got the same problem. It's working on npm run dev but not after getting static build next build && next export. I'm using Next.js 13 with Page Routing.

Upvotes: 2

Mohammad Mohagheghian
Mohammad Mohagheghian

Reputation: 483

For me, it is solved by changing

import "swiper/css";

to

import "swiper/swiper.min.css";

Upvotes: 4

Douglas Henrique
Douglas Henrique

Reputation: 321

Solved. I inserted the swiper styles classes at my main styles global.scss and worked. Thank you guys!

Upvotes: 9

iunfixit
iunfixit

Reputation: 994

Assuming the css class names are correct, change the order of your imports

import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';

import styles from './slider.module.scss'

Upvotes: 0

Related Questions