Closed2

Next.jsのMiddlewareでセットしたCookieがRSCでリロードしないと反映されない

Yuta KobayashiYuta Kobayashi

一時的な解決策ではあるけどこうした。リダイレクトにしてしまうとCookieがセットできない環境で無限ロードされる可能性がある

import { NextResponse, type NextRequest } from "next/server";
import {
  ResponseCookies,
  RequestCookies,
} from "next/dist/server/web/spec-extension/cookies";
import acceptLanguage from "accept-language";
import { languages, cookieName, fallbackLng } from "@/lib/i18n/i18n";

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js).*)"],
};

acceptLanguage.languages(languages);

/**
 * Copy cookies from the Set-Cookie header of the response to the Cookie header of the request,
 * so that it will appear to SSR/RSC as if the user already has the new cookies.
 */
function applySetCookie(req: NextRequest, res: NextResponse): void {
  // parse the outgoing Set-Cookie header
  const setCookies = new ResponseCookies(res.headers);
  // Build a new Cookie header for the request by adding the setCookies
  const newReqHeaders = new Headers(req.headers);
  const newReqCookies = new RequestCookies(newReqHeaders);
  setCookies.getAll().forEach((cookie) => newReqCookies.set(cookie));
  // set “request header overrides” on the outgoing response
  NextResponse.next({
    request: { headers: newReqHeaders },
  }).headers.forEach((value, key) => {
    if (
      key === "x-middleware-override-headers" ||
      key.startsWith("x-middleware-request-")
    ) {
      res.headers.set(key, value);
    }
  });
}

export default function middleware(req: NextRequest) {
  // Set cookies on your response
  const res = NextResponse.next();

  const hasCookie = req.cookies.has(cookieName);

  // If cookie does not exist
  if (!hasCookie) {
    // Get language from Accept-Language header
    const acceptedLanguage =
      acceptLanguage.get(req.headers.get("Accept-Language")) || fallbackLng;

    res.cookies.set(cookieName, acceptedLanguage);
  }

  // Apply those cookies to the request
  applySetCookie(req, res);

  return res;
}
このスクラップは5ヶ月前にクローズされました