← Back to list

How to Use Swiper in Angular 20 and Change Direction Based on Language

A Swiper carousel that flips direction instantly when switching between English (LTR) and Arabic (RTL).

Ahmed Abdelaziz · 2025-08-12 11:20 · 7 claps · 3.2 min read
#angular #swiper #front-end-development #multilingual-websites #web-development
Open on Medium ↗
Wiki topics: LNG · Linguistics & Language 🌐 · Web Development

How to Use Swiper in Angular 20 and Change Direction Based on Language

A Swiper carousel that flips direction instantly when switching between English (LTR) and Arabic (RTL).

When building multilingual Angular applications, it’s common to switch between LTR (Left-to-Right) and RTL (Right-to-Left) layouts depending on the selected language.

If your app uses a Swiper carousel, you might want it to automatically change its scrolling direction whenever the language changes — for example, when switching between English (ltr) and Arabic (rtl).

In this guide, we’ll walk through building a Swiper that:

  • Initializes with the correct direction based on the current language
  • Reacts instantly to language changes
  • Flips navigation arrows automatically

1. Why We Need Dynamic Direction

Languages like English, French, and Spanish are left-to-right, while languages like Arabic and Hebrew are right-to-left.

If you keep your Swiper carousel fixed to LTR, Arabic users will see navigation arrows in the wrong place and the slides will move in the opposite direction.

We can solve this by:

  • Listening for language changes
  • Updating the Swiper’s direction
  • Adjusting CSS styles accordingly

2. Setting Up the Language Service

We’ll use @ngx-translate/core to handle language switching and Angular’s new signals for reactivity.

// language.service.ts
import { isPlatformBrowser } from '@angular/common';
import { effect, Inject, inject, Injectable, PLATFORM_ID, signal } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Injectable({ providedIn: 'root' })
export class LanguageService {
  currentLang = signal<string>('en');
  private translateService = inject(TranslateService);

  constructor(@Inject(PLATFORM_ID) readonly platformId: Object) {
    if (isPlatformBrowser(this.platformId)) {
      this.currentLang.set(localStorage.getItem('lang') || this.currentLang());
    }

    this.translateService.setDefaultLang(this.currentLang());
    this.translateService.use(this.currentLang());

    effect(() => {
      const lang = this.currentLang();
      this.translateService.use(lang);
      this.setHtmlLangAttribute(lang);
    });
  }

  private setHtmlLangAttribute(lang: string) {
    if (typeof document !== 'undefined') {
      document.documentElement.setAttribute('lang', lang);
      document.documentElement.setAttribute('dir', lang === 'ar' ? 'rtl' : 'ltr');
      localStorage.setItem('lang', lang);
    }
  }

  switchLanguage(lang: string) {
    this.currentLang.set(lang);
  }
}

Highlights:

  • We store the selected language in localStorage.
  • We update <html dir="rtl"> or <html dir="ltr"> to apply direction globally.
  • Signals (currentLang) ensure reactive updates anywhere in the app.

3. Creating a Swiper Directive for Angular

We’ll create a directive to:

  • Initialize Swiper with the given config
  • Listen for language changes
  • Update Swiper’s direction in real-time
// swiper.directive.ts
import { isPlatformBrowser } from '@angular/common';
import { AfterViewInit, Directive, effect, ElementRef, inject, Inject, Input, PLATFORM_ID, signal } from '@angular/core';
import { SwiperContainer } from 'swiper/element';
import { SwiperOptions } from 'swiper/types';
import { LanguageService } from '../../core/services/language.service';

@Directive({
  selector: '[appSwiper]'
})
export class SwiperDirective implements AfterViewInit {
  @Input() config?: SwiperOptions;
  languageService = inject(LanguageService);
  dir = signal<string>(this.languageService.currentLang() === 'ar' ? 'rtl' : 'ltr');

  constructor(
    private el: ElementRef<SwiperContainer>,
    @Inject(PLATFORM_ID) readonly platformId: Object
  ) {
    effect(() => {
      const direction = this.languageService.currentLang() === 'ar' ? 'rtl' : 'ltr';
      this.dir.set(direction);
      if (isPlatformBrowser(this.platformId) && this.el.nativeElement?.swiper) {
        this.el.nativeElement.swiper.changeLanguageDirection(direction as 'ltr' | 'rtl');
      }
    });
  }

  ngAfterViewInit(): void {
    if (!this.config) {
      console.warn('SwiperDirective: No configuration provided.');
      return;
    }

    Object.assign(this.el.nativeElement, this.config);

    if (isPlatformBrowser(this.platformId)) {
      this.el.nativeElement.initialize();
      if (this.el.nativeElement.swiper) {
        this.el.nativeElement.swiper.changeLanguageDirection(this.dir() as 'ltr' | 'rtl');
      }
    }
  }
}

Highlights:

  • We use effect() to react to language changes automatically.
  • Swiper’s changeLanguageDirection() is called whenever the language updates.
  • We prevent initialization on the server to avoid SSR issues.

4. Using Swiper in a Component

<!-- banner.html -->
<section class="container hero-banner relative mb-3.5">
  <swiper-container appSwiper #swiper [config]="swiperConfig" init="false">
    @for(img of images; track $index;) {
      <swiper-slide>
        <figure>
          <img
            class="w-full rounded-xl object-cover min-h-[224px]"
            [src]="img"
            alt="Slide"
          />
        </figure>
      </swiper-slide>
    }
  </swiper-container>

  <button class="banner-prev"></button>
  <button class="banner-next"></button>
</section>
// banner.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { SwiperDirective } from '../../directives/swiper.directive';
import { SwiperOptions } from 'swiper/types';

@Component({
  selector: 'app-banner',
  imports: [SwiperDirective],
  templateUrl: './banner.html',
  styleUrl: './banner.css',
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class Banner {
  images = [
    'https://dummyimage.com/1200x300/000/fff',
    'https://dummyimage.com/1200x300/111/fff',
    'https://dummyimage.com/1200x300/222/fff'
  ];

  swiperConfig: SwiperOptions = {
    slidesPerView: 1,
    navigation: {
      nextEl: '.banner-next',
      prevEl: '.banner-prev'
    }
  };
}

5. Styling Navigation Buttons with Tailwind

We can use Tailwind’s ltr: and rtl: variants to position arrows correctly:

@layer utilities {
  button[class*="-prev"] {
    @apply absolute top-[50%] ltr:left-[-15px] rtl:right-[-15px] rtl:rotate-180 transform -translate-y-1/2 z-10;
  }

  button[class*="-next"] {
    @apply absolute top-[50%] ltr:right-[-15px] rtl:left-[-15px] rtl:rotate-180 transform -translate-y-1/2 z-10;
  }
}

/* When you switch the app language to Arabic, the buttons automatically flip sides. */

6. The Result

✅ Swiper initializes with the correct direction for the current language ✅ Changes direction instantly when switching between en and ar ✅ Navigation arrows also flip automatically

This approach works well with Angular 20’s standalone components and signals.

7. Final Thoughts

Using Angular signals with a Swiper directive is a clean, reactive way to handle language-based direction changes.

It keeps the Swiper setup reusable and independent, while your LanguageService manages global language state.


메타데이터
post_id
4483b257be54
slug
how-to-use-swiper-in-angular-20-and-change-direction-based-on-language-4483b257be54
url
https://medium.com/@zizo.climbs/how-to-use-swiper-in-angular-20-and-change-direction-based-on-language-4483b257be54
canonical_url
https://medium.com/@zizo.climbs/how-to-use-swiper-in-angular-20-and-change-direction-based-on-language-4483b257be54
author_url
https://medium.com/@zizo.climbs
status
ok
fetched_at
2026-07-18 07:05:27