Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local storage is not defined in angular 17

Recently I am migrate angular from 16 to 17 and start showing localStorage is not defined error. I saw some solutions to disable ssr from angular.json

From

"server": "src/main.server.ts",
"prerender": true,
"ssr": {
  "entry": "server.ts"
}

To

"server": "src/main.server.ts",
"prerender": false,
"ssr": false

and it worked but is want to know there is an other way to use local storage without disabling ssr.

like image 526
prashant kushwah Avatar asked Nov 22 '25 04:11

prashant kushwah


2 Answers

A simple solution would be to access localStorage through the DOCUMENT DI token.

Here is a standalone component that you can use to verify that it works for you. It worked in my local environment using SSR in development mode.

import { Component, Inject } from '@angular/core';
import { CommonModule, DOCUMENT } from '@angular/common';

@Component({
  selector: 'app-test',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './test.component.html',
  styleUrl: './test.component.scss'
})
export class TestComponent {
  constructor(@Inject(DOCUMENT) private document: Document) {
    const localStorage = document.defaultView?.localStorage;

    if (localStorage) {
      const counter = localStorage.getItem('counter');

      if (counter) {
        localStorage.setItem('counter', (parseInt(counter) + 1).toString());
      } else {
        localStorage.setItem('counter', '1');
      }
    }
  }
}

Here are some links for more information:

  • Important Considerations when Using Angular Universal
  • Supply a custom provider with @Inject
like image 190
John Avatar answered Nov 23 '25 16:11

John


Angular 17 basically comes with Fundamental changes in the Framework's architecture. Since you enabled SSR in your project, and if you are trying to access Localstorage or Sessionstorage from Constructor or any possible Lifecycles which will trigger in SSR will throw the above error u were getting. So if you feel you want to use some storage mechanism in Component initialisation then please wrap the storage access or setting code in an if condition. Please refer the below code;

constructor(@Inject(PLATFORM_ID) private platformId: Object) {
if (isPlatformBrowser(this.platformId)) {
  this.currentUserSubject = new BehaviorSubject<UserInfo>(
    JSON.parse(sessionStorage.getItem('userInfo'))
  );
}

}

So if you see the above code snippet, I had wrapped the sessionStorage related code inside an if condition. isPlatformBrowser(this.platformId) this gonna check if the user is in Browser or not. You may can try the above solution.

like image 30
Harikrishnan Varieth Avatar answered Nov 23 '25 16:11

Harikrishnan Varieth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!