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. 🌐