Torihaji's Growth Diary

Little by little, no hurry.

クライアント側でランダム値を生成するならHydration Errorに注意

はじめに

github oauthやろうとしていて,

普通にUI作ってたらHydration Errorなって、詰まったのでその備忘録です。

やってたこと

"use client";

import Image from "next/image";
import Link from "next/link";

export const GithubButton = () => {
  const clientId = process.env.NEXT_PUBLIC_GITHUB_CLIENT_ID;
  const redirectUri = process.env.NEXT_PUBLIC_GITHUB_REDIRECT_URI;
  const scope = "read:user";
  const state = crypto.randomUUID();
  const url = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${state}`;

  return (
    <Link
      href={url}
      className="flex items-center gap-2 bg-white text-black px-4 py-2 rounded-md"
    >
      <Image src="/github-mark.svg" alt="GitHub" width={20} height={20} />
      Login with GitHub
    </Link>
  );
};

めちゃめちゃ最低限なgithub loginボタン作ってました。

そしたらhydration errorってでまして。

で、hydration errorというのは あらかじめserver 側で作ったものと クライアント側で作ったものの不一致から起こるエラーです。

今回の原因は その stateを作るために使ってたrandomUUIDが原因です。

なのでそれをブラウザ側だけで作るようにしました。

"use client";

import Image from "next/image";
import Link from "next/link";
import { useState, useEffect } from "react";

export const GithubButton = () => {
  const [url, setUrl] = useState("");

  useEffect(() => {
    const clientId = process.env.NEXT_PUBLIC_GITHUB_CLIENT_ID;
    const redirectUri = process.env.NEXT_PUBLIC_GITHUB_REDIRECT_URI;
    const scope = "read:user";
    const state = crypto.randomUUID();
    const generatedUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${state}`;
    setUrl(generatedUrl);
  }, []);

  return (
    <Link
      href={url}
      className="flex items-center gap-2 bg-white text-black px-4 py-2 rounded-md"
    >
      <Image src="/github-mark.svg" alt="GitHub" width={20} height={20} />
      Login with GitHub
    </Link>
  );
};

他にやり方あるかもしれませんがこれにて解決です。

単純ですけど、引っかかりやすいですね。

終わりに

終わり。