In autumn 2022, I decided to migrate one of our work projects from the Create React App to NextJs. The goal of this was to increase the performance of a few pages, separate pages for mobile devices from the main app, and decrease the number of 3rd parties with access. Most of our goals were achieved successfully but according to our Airbrake notifier, was always breaking something. I hadn’t previously considered that would be a challenge, as I had been storing users’ phone numbers and i18n keys there and couldn't use a backend API instead. localStorage localStorge So, I needed localStorage to work since it was the only option for me. My challenges One problem I faced was an error at compile time. ReferenceError: localStorage is not defined Yeah, I was definitely a newbie to NextJs and totally missed the fact that my pages perform server render first and foremost. Meaning that and wouldn't be accessible until the page is loaded on the client’s side. window localStorage import { useEffect } from 'react'; useEffect(() => { const phoneNumber = localStorage.getItem('phoneNumber'); }, []); // and const onChange = value => localStorage.setItem('phoneNumber', value); The solution was quite simple, to put everything related to it into and handlers to make sure it reflects in the browser. useEffect onChange The second and the third were my biggest problems because I managed to solve them only after reading lots of articles, posts, and documentation pages. SecurityError: The operation is insecure. We received this error only from the Safari browser, so I decided to dig a little further. I found an interesting fact. If all cookies in privacy and security settings are blocked by the user, every time your website calls either or it will cause an error. localStorage sessionStorage // Even calling console.log(localStorage); // or localStorage?.getItem('phoneNumber'); Wrapping everything in wasn’t a good option because it would increase the existing codebase, which is bad practice. Following the code snippet on , I decided to write a utility class that would cover all vital components related to the . try...catch MDN localStorage class AppStorage { getItem(key) { if (this.storageAvailable()) { return window.localStorage?.getItem(key); } return undefined; } setItem(key, value) { if (this.storageAvailable()) { window.localStorage?.setItem(key, value); } } storageAvailable(type = 'localStorage') { let storage; try { storage = window[type]; const x = '__storage_test__'; storage.setItem(x, x); storage.removeItem(x); return true; } catch (e) { return ( e instanceof DOMException && // everything except Firefox (e.code === 22 || // Firefox e.code === 1014 || // test name field too, because code might not be present // everything except Firefox e.name === 'QuotaExceededError' || // Firefox e.name === 'NS_ERROR_DOM_QUOTA_REACHED') && // acknowledge QuotaExceededError only if there's something already stored storage && storage.length !== 0 ); } } } // and inside our components const phoneNumber = AppStorage.getItem('phoneNumber'); Looks quite elegant, doesn’t it? We have this utility class in a separate file and can use it across the app by applying the D . By the way, this utility class also helped to solve the last problem: RY strategy TypeError: Cannot read properties of null (reading 'setItem') Airbrake sent us that error from Android on new versions of Chrome. I still haven’t figured out what caused it, because the operator didn't help, was defined. But it was . .? window.localStorage null I really hope it will be fixed in the nearest months or years and Browser API will be unified across all browsers. Yes, I’m a dreamer. And of course, I believe this article and my experience will help someone who is struggling with crashes. localStorage