Window and document are unavailable on the server. So you'll run into errors such as ReferenceError: window is not defined if you are trying to access document or window properties such as local storage.
To avoid these undefined errors at compile and build time, you can run a simple check, and only if a user is a browser user run your code.
Since process.browser is deprecated you must use typeof window.
if (typeof window !== "undefined") {
// Write your client-side statements here.
window.localStorage.getItem("key");
window.localStorage.setItem("key", "value");
}
Optimal solution:
This is good and it'll work, but you need to explicitly check if it is a client-side rendered component or server-side every time.
To avoid this issue you need to create an mock window object.
then use mock window for server-side logic and actual window for client-side.
let WINDOW = {};
if (typeof window !== "undefined") {
// When code is on client-side. So we need to use actual methods and data.
WINDOW = window;
} else {
// When code is on server-side.
// Other component are mostly server-side and need to match their logic and check their variable with other server-side components and logics.
// So following code will be use for them to pass the logic checking.
WINDOW = {
document: {
location: {},
},
localStorage: {
getItem :() => {},
setItem :() => {}
},
};
}
export default WINDOW;
Note that: Depending on what property of window, document,... or what methods of those property you have used, your implementation details will be different.
Now use WINDOW instead of window in your code:
WINDOW.localStorage.getItem("key");
WINDOW.localStorage.setItem("key", "value");
Example of use:
I created a custom hook for using local storage:
export const useLocalStorage = (key) => {
// returns value related to initial key.
const item = WINDOW.localStorage.getItem(key);
// return an function that will save given value to initial key
const setItem = (value) => WINDOW.localStorage.setItem(key, value);
return [item, setItem];
};
Warning:
remember, never create a function for window type checking.
it always must be an explicit type checking or it will not work
Wrong way:
const hasWindow = () => {
return typeof window !== "undefined"
}
if (hasWindow()) {
// client-side operation such as local storage.
localStorage.setItem(key, value)
}
if (!hasWindow()) {
// server-side code
}
read more and reason for this problem: and it's a copy-paste of similar post written by him.
SOCIAL SHARE CARD GENERATOR