Client component and browser API
The process of how I resolved using browser API in the client component in Next.js.
Client Component
There are two types of components in Next.js: server components and client components.
As documentation stated, client component could be beneficial especially for interactive UI and browser APIs. We can simply add use client
directive at the very top of the component in order to make it as the client component.
How is client component rendered?
It is often misunderstood that client component is rendered in the browser 100%, which is NOT correct. With taking advantage of React's API, Next lets the static HTML preview be shown on the server for both server and client component, so that users can see the content of the page in no time. Below is the diagram of how Next.js renders client component1.
What is hydration?
Hydration indicates the process of attaching e vent listeners to the DOM in order to make static HTML be UI interactive with using React's API hydrateRoot
.
What Happened?
I was making a splash animation that sholud be only once by the time users visit my website unless they close the browser window.
To do this, I needed to use sessionStorage
from Window interface.
- Check if there is
splash
key insessionStorage
, which checks whether or not splash animation has been implemented. - If there is no
splash
key (e.g.sessionStorage.getItem("splash") === null
2), that means splash animation should be run. If so, create newsplash
key and set its value to"true"
(e.g.sessionStorage.setItme("splash", "true")
3) - Set the time delay for setting
splash
key to have its value of"true"
after total duration time of splash animation with usingsetTimeout()
method.
As we have gone through that client component is also rendered on the server first,
we cannot simply access to window
object because server-side (Node.js) context has neither DOM or browser APIs.
Therefore, I got an error of ReferenceError(): window is not defined
during production process.
Workarounds
There are two ways I found out to solve this error according to
Skipping SSR
next/dynamic
has option for allowing us to skip SSR
by adding ssr: false
.
By doing this, we can force to cancel SSR so that component should only be run on pure client-side.
Using useEffect
hook
This is the traditional way to access sessionStorage
with using useEffect
hook.
// ...
useEffect(() => {
if (sessionStorage.getItem("splash") === null) {
sessionStorage.setItem("splash", "true");
setSplashAnimated(true);
}
}, []);
// ...