Angular Universal LocalStorage Hatası (SSR) Nasıl Düzeltilir?

Bu yazımda, Angular Universal yükledikten sonra localStorage kullanımı sırasında alınan “ERROR ReferenceError: localStorage is not defined” hatasının nedenini ve çözümünü adım adım anlatacağım.

Hatanın Nedeni Nedir?

Bu hata, Angular Universal (SSR) kullanıldığında karşımıza çıkar. Çünkü localStorage nesnesi yalnızca tarayıcı (client-side) ortamında mevcuttur. Node.js üzerinde çalışan sunucu tarafında (server-side) localStorage bulunmadığı için bu hata oluşur.

Angular SSR'nin Server-Side veya Client-Side'da Çalıştığını Belirleme

Öncelikle uygulamanın tarayıcıda mı yoksa sunucuda mı çalıştığını anlamamız gerekir.

Adım 1: Çalışma Ortamını Belirleme

app.component.ts dosyasına aşağıdaki kodu ekleyin:

import { Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { BehaviorSubject } from 'rxjs';
import { Router } from '@angular/router';

export class AppComponent {
  static isBrowser = new BehaviorSubject(null);

  constructor(@Inject(PLATFORM_ID) private platformId: any, private _router: Router) {
    AppComponent.isBrowser.next(isPlatformBrowser(platformId));
  }
}

Bu kod sayesinde, Angular uygulamasının tarayıcı veya sunucu tarafında çalıştığını tespit edebiliriz.

LocalStorage Servisini Oluşturma

Uygulama server-side çalıştığında localStorage doğrudan kullanılamaz. Bu yüzden, RxJS tabanlı bir soyutlama servisi oluşturacağız.

Localstorage.service.ts Dosyası

import { Injectable } from '@angular/core';
import { AppComponent } from '../../app.component';

class LocalStorage implements Storage {
  [name: string]: any;
  readonly length: number;

  clear(): void {}
  getItem(key: string): string | null { return undefined; }
  key(index: number): string | null { return undefined; }
  removeItem(key: string): void {}
  setItem(key: string, value: string): void {}
}

@Injectable({ providedIn: 'root' })
export class LocalstorageService implements Storage {
  private storage: Storage;

  constructor() {
    this.storage = new LocalStorage();
    AppComponent.isBrowser.subscribe(isBrowser => {
      if (isBrowser) {
        this.storage = localStorage;
      }
    });
  }

  [name: string]: any;
  length: number;

  clear(): void { this.storage.clear(); }
  getItem(key: string): string | null { return this.storage.getItem(key); }
  key(index: number): string | null { return this.storage.key(index); }
  removeItem(key: string): void { return this.storage.removeItem(key); }
  setItem(key: string, value: string): void { this.storage.setItem(key, value); }
}

Açıklama:

  • LocalStorage sınıfı, SSR sırasında hata alınmaması için boş metotlarla tanımlanmıştır.
  • AppComponent.isBrowser değeri sayesinde uygulamanın tarayıcıda olup olmadığı kontrol edilir.
  • Tarayıcı ortamında çalışıyorsa localStorage aktif hale getirilir.

Local Storage Servisini Kullanma

Artık oluşturduğumuz LocalstorageService’i herhangi bir component içinde kullanabiliriz.

Örnek Kullanım

constructor(
  private authService: AuthenticationService,
  private router: Router,
  private localStorage: LocalstorageService
) {
  this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
  this.router.routeReuseStrategy.shouldReuseRoute = () => false;
  
  this.mySubscription = this.router.events.subscribe((event) => {
    if (event instanceof NavigationEnd) {
      this.router.navigated = false;
    }
  });
}

ngOnInit İçinde Kullanım

ngOnInit() {
  this.currentUser = JSON.parse(this.localStorage.getItem('currentUser'));
  this.isLoggedIn$ = this.currentUser !== null;
}

Bu sayede, SSR ortamında localStorage kullanımı sırasında artık hata almayacaksınız.

Sonuç

Bu yazıda, Angular Universal (SSR) kullanırken alınan localStorage is not defined hatasının çözümünü öğrendik. Özetle:

  • Uygulamanın tarayıcıda mı yoksa sunucuda mı çalıştığını belirledik.
  • Güvenli bir localStorage servisi oluşturduk.
  • Servisi component’lerde kullanarak sorunsuz şekilde localStorage’a eriştik.

Artık Angular 15 Universal projelerinizde SSR uyumlu localStorage kullanımını güvenle gerçekleştirebilirsiniz. Daha fazla Angular rehberi için web sitemizi ziyaret edebilirsiniz. 🌐

Beğendiysen bir çay ısmarlayabilirsin ☕

Bana çay ısmarla

FrontEnd ile ilgili yorumlar

Yorum Paylaş

EMail Zorunlu alanlar * *