-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Closed
Labels
Description
Describe what's incorrect/missing in the documentation
Summary
When setting a cookie from client-side JavaScript using document.cookie, the server-side createCookie().parse() returns an empty object instead of the cookie value, even though the cookie header is correctly received.
Reproduction
1. Create cookie utility (app/lib/theme.server.ts)
import { createCookie } from "react-router";
export const themeCookie = createCookie("theme", {
maxAge: 60 * 60 * 24 * 365,
httpOnly: false,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
path: "/",
});
export async function getTheme(request: Request): Promise<string | null> {
const cookieHeader = request.headers.get("Cookie");
console.log("Cookie header:", cookieHeader);
const parsed = await themeCookie.parse(cookieHeader);
console.log("Parsed:", parsed);
return parsed;
}2. Set cookie from client (app/components/theme-toggle.tsx)
const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
// Set plain cookie from client
document.cookie = `theme=${newTheme}; path=/; max-age=31536000; SameSite=Lax`;
revalidator.revalidate();
};3. Observe server logs
Cookie header: theme=dark; __session=eyJ1c2VySWQi...
Parsed: {}
Expected Behavior
createCookie().parse() should return "dark" or the cookie value.
Actual Behavior
Returns empty object {} despite cookie being present in header.
Workaround
Manual cookie parsing works:
const cookies = cookieHeader.split(';').reduce((acc, cookie) => {
const [key, value] = cookie.trim().split('=');
acc[key] = value;
return acc;
}, {} as Record<string, string>);
const theme = cookies.theme; // Works!Environment
- React Router: v7 (latest)
- SSR: enabled
- Node: v20+
Is createCookie().parse() only intended to work with signed/sealed cookies created by the framework? If so, this should be documented. If plain cookies should work, this appears to be a bug.