Next.js Discord

Discord Forum

localStorage not defined in client component

Answered
Savannah posted this in #help-forum
Open in Discord
Avatar
SavannahOP
I have a component that provides user for every component in my project via context. It is defined like so:

"use client"

import { User } from "@/types/database"
import { createContext, useState } from "react"
import { AuthContextType } from "@/types/contexts"
import { retrievePreviousUser } from "@/lib/database"

export const AuthContext = createContext<AuthContextType>({
  user: null,
  setUser: () => {},
})

function AuthProvider({ children }: {children: React.ReactNode}) {
  const [ user, setUser ] = useState<User | null>(retrievePreviousUser)

  return (
    <AuthContext.Provider value={{user, setUser}}>
        {children}
    </AuthContext.Provider>
  )
}

export default AuthProvider


function retrievePreviousUser accesses localStorage and retrieves user if it's present in the browser memory. However, when site loads I'm receiving this error in the console:

src\lib\database.ts (11:17) @ localStorage
 ⨯ ReferenceError: localStorage is not defined
    at getMeta (./src/lib/database.ts:17:18)
    at retrievePreviousUser (./src/lib/database.ts:51:22)    
    at AuthProvider (./src/components/AuthProvider.tsx:19:76)
   9 |
  10 | function getMeta(): MetaScheme {
> 11 |     const data = localStorage.getItem("meta")


Why is this happening? And even though I'm getting error, it still loads. Just barely flashes error screen for a millisecond.
Answered by Ray
because client component will also be rendered on server so you need to do something like this
 const [meta, setMeta] = useState<string|null>(null);

  useEffect(() => {
    const meta = localStorage.getItem("meta");
    setMeta(meta);
  }, []);
View full answer

9 Replies

Avatar
Ray
because client component will also be rendered on server so you need to do something like this
 const [meta, setMeta] = useState<string|null>(null);

  useEffect(() => {
    const meta = localStorage.getItem("meta");
    setMeta(meta);
  }, []);
Answer
Avatar
SavannahOP
Hmm. Why would it need to do that? Is it alright that it will always return null on server?
For example, it doesn't try to render client components with useState or useEffect on server
Why it does this when I'm accessing localStorage?
Avatar
Ray
it does
Image
Avatar
SavannahOP
Can you give me a link? I'd read this article
Avatar
SavannahOP
I thought it just ignores client components on server
Thanks!