angularserver-side-renderingswiper.jsangular17angular17-ssr

Swiper 11 Angular 17 SSR Swiper breakpoints not working


I'm currently facing challenges in integrating breakpoints into the swiper code. Despite my attempts, I have been unable to successfully implement the breakpoints, and it appears that the functionality is not working as expected. I'm reaching out to inquire if anyone else has encountered similar issues or if there are success stories regarding the implementation of breakpoints in this specific code. Any guidance or insights into resolving this matter would be greatly appreciated.

HTML:

<div>
    <swiper-container style="--swiper-navigation-color: #fff; --swiper-pagination-color: #fff" class="mySwiper"
    thumbs-swiper=".mySwiper2" space-between="10" navigation="true">
    <swiper-slide *ngFor="let slide of slides">
      <img [src]="slide.image" />
    </swiper-slide>
  </swiper-container>

  <swiper-container class="mySwiper2" space-between="10" slides-per-view="6" free-mode="true"
    watch-slides-progress="true">
    <swiper-slide *ngFor="let slide of slides">
      <img [src]="slide.image" />
    </swiper-slide>
  </swiper-container>

</div>

SCSS:

/* You can add global styles to this file, and also import other style files */
    swiper-slide {
      text-align: center;
      font-size: 18px;
      background: #fff;
      display: flex;
      justify-content: center;
      align-items: center;
      background-size: cover;
      background-position: center;
      img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }

    .mySwiper {
    // defines height and width of main swiper
      height: 600px;
      width: 600px;
    }

    .mySwiper2 {
      // defines height and width of thumbs swiper
      height: 100px;
      width: 600px;
      box-sizing: border-box;
      padding: 10px 0;
      swiper-slide {
        opacity: 0.6; // this set default opacity to all slides
      }
      .swiper-slide-thumb-active {
        opacity: 1; // this reset the opacity one for the active slide
      }
    }

TS:

    import { CommonModule } from '@angular/common';
    import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
    
    @Component({
      selector: 'app-thumbs-default',
      standalone: true,
      imports: [CommonModule],
      templateUrl: './thumbs-default.component.html',
      styleUrl: './thumbs-default.component.scss',
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    export class ThumbsDefaultComponent {
    
      slides = [
    {image: 'https://swiperjs.com/demos/images/nature-1.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-2.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-3.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-4.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-5.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-6.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-7.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-8.jpg'},
    {image: 'https://swiperjs.com/demos/images/nature-10.jpg'}
  ];
    
    }

Solution

  • I am unable to perform the breakpoint initialization directly through HTML attributes, so to get break points, I programmatically initialize then through ViewChild and ngAfterViewInit. Also to get breakpoints to works, we should not set a pixel width to the slides, I think that was causing issues in your code!

    ts

    import { CommonModule } from '@angular/common';
    import {
      Component,
      OnInit,
      CUSTOM_ELEMENTS_SCHEMA,
      ViewChild,
      ElementRef,
    } from '@angular/core';
    
    @Component({
      selector: 'app-swiper',
      standalone: true,
      imports: [CommonModule],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      templateUrl: './swiper.component.html',
    })
    export class SwiperComponent implements OnInit {
      @ViewChild('swiper2') swiper2!: ElementRef<any>;
      slides = [
        { image: 'https://swiperjs.com/demos/images/nature-1.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-2.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-3.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-4.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-5.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-6.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-7.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-8.jpg' },
        { image: 'https://swiperjs.com/demos/images/nature-10.jpg' },
      ];
      constructor() {}
    
      ngOnInit() {}
    
      ngAfterViewInit() {
        const swiperParams = {
          breakpoints: {
            100: {
              slidesPerView: 3,
            },
            640: {
              slidesPerView: 5,
            },
            1024: {
              slidesPerView: 6,
            },
          },
        };
    
        // now we need to assign all parameters to Swiper element
        Object.assign(this.swiper2.nativeElement, swiperParams);
        this.swiper2.nativeElement.initialize();
      }
    
      setupImageZoom() {
        alert('setting up zoom!');
      }
    }
    

    html

    <div>
      <swiper-container
        style="--swiper-navigation-color: #fff; --swiper-pagination-color: #fff"
        class="mySwiper"
        thumbs-swiper=".mySwiper2"
        space-between="10"
        navigation="true"
      >
        <swiper-slide *ngFor="let slide of slides">
          <img [src]="slide.image" />
        </swiper-slide>
      </swiper-container>
    
      <swiper-container
        #swiper2
        class="mySwiper2"
        space-between="10"
        slides-per-view="6"
        free-mode="true"
        watch-slides-progress="true"
        init="false"
      >
        <swiper-slide *ngFor="let slide of slides">
          <img [src]="slide.image" />
        </swiper-slide>
      </swiper-container>
    </div>
    

    scss

    /* Add application styles & imports to this file! */
    @import 'swiper/css';
    @import 'swiper/css/navigation';
    @import 'swiper/css/pagination';
    
    /* You can add global styles to this file, and also import other style files */
    swiper-slide {
      text-align: center;
      font-size: 18px;
      background: #fff;
      display: flex;
      justify-content: center;
      align-items: center;
      background-size: cover;
      background-position: center;
      img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }
    
    .mySwiper {
      height: 600px;
      width: 100%;
    }
    
    .mySwiper2 {
      // defines height and width of thumbs swiper
      height: 100px;
      width: 100%;
      box-sizing: border-box;
      padding: 10px 0;
      swiper-slide {
        opacity: 0.6; // this set default opacity to all slides
      }
      .swiper-slide-thumb-active {
        opacity: 1; // this reset the opacity one for the active slide
      }
    }
    

    stackblitz demo