Skip to main content

Client component and browser API

· 3 min read

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.



info

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.

  1. Check if there is splash key in sessionStorage, which checks whether or not splash animation has been implemented.
  2. If there is no splash key (e.g. sessionStorage.getItem("splash") === null2), that means splash animation should be run. If so, create new splash key and set its value to "true" (e.g. sessionStorage.setItme("splash", "true")3)
  3. Set the time delay for setting splash key to have its value of "true" after total duration time of splash animation with using setTimeout() 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);
}
}, []);
// ...

Solution

Footnotes

  1. How are Client Components Rendered?

  2. getItem() method

  3. setItem() method