Next.js Discord

Discord Forum

Accessing document instance in client component throws error

Answered
Philippine Crocodile posted this in #help-forum
Open in Discord
Philippine CrocodileOP
// src/hooks/cookies.tsx

"use client"

import { useState } from "react";

export const useCookies = (key: string) => {
    const [c] = useState(() => {
        const cookie = document.cookie.split(";").find(t => t.split('=')[0].trim() === key);
        return cookie?.split('=')[1].trim()
    });
    return c;
}


It is working completely fine but shows this error in on pages
Answered by Transvaal lion
You can use this.

'use client';
import { useSyncExternalStore } from 'react';

function readCookie(key: string): string | null {
  if (typeof document === 'undefined') return null;
  const cookie = document.cookie
    .split(';')
    .find((t) => t.split('=')[0].trim() === key);
  return cookie ? decodeURIComponent(cookie.split('=')[1].trim()) : null;
}

export const useCookies = (key: string) => {
  return useSyncExternalStore(
    () => () => {},
    () => readCookie(key),
    () => null,
  );
};

Better to pass cookies from server component to client component or use library like js-cookie/cookies-next. Also can go through this discussion https://github.com/vercel/next.js/discussions/79665
View full answer

4 Replies

Transvaal lion
Even if it is client component, nextjs will try to prerender it and document will be undefined. You should read cookies in useEffect
Philippine CrocodileOP
using useEffect hook gives build errors, saying you might not need to use useEffect
Transvaal lion
You can use this.

'use client';
import { useSyncExternalStore } from 'react';

function readCookie(key: string): string | null {
  if (typeof document === 'undefined') return null;
  const cookie = document.cookie
    .split(';')
    .find((t) => t.split('=')[0].trim() === key);
  return cookie ? decodeURIComponent(cookie.split('=')[1].trim()) : null;
}

export const useCookies = (key: string) => {
  return useSyncExternalStore(
    () => () => {},
    () => readCookie(key),
    () => null,
  );
};

Better to pass cookies from server component to client component or use library like js-cookie/cookies-next. Also can go through this discussion https://github.com/vercel/next.js/discussions/79665
Answer