Remix Cookies — Direct Cookie Management
In this tutorial, you will learn about Remix Cookies. We cover key concepts, practical examples, and best practices to help you master this topic.
Learn Remix cookies: create and manage cookies directly, set cookie attributes, read cookies in loaders and actions, and sign cookies for security.
In this lesson, you'll use Remix's cookie API to create, read, and write cookies directly without the session abstraction layer.
What You'll Learn
How to create cookies, read them in loaders, set them in actions, configure cookie attributes, and sign cookies for integrity.
Why It Matters
Cookies are useful for simple state like theme preferences, language settings, or A/B test assignments. Direct cookie access is simpler than sessions for single-value storage.
Real-World Use
DodaZIP stores user theme preference (light/dark), language choice, and dismissed announcements in cookies for instant access.
flowchart LR
A[Create Cookie] --> B[Loader: Read]
A --> C[Action: Write]
B --> D[Component: Use Value]
C --> E[Set-Cookie Header]
style A fill:#121212,color:#fff
Creating a Cookie
// app/cookies.server.ts
import { createCookie } from "@remix-run/node";
export const themeCookie = createCookie("theme", {
maxAge: 60 * 60 * 24 * 365, // 1 year
httpOnly: true,
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
});
export const languageCookie = createCookie("lang", {
maxAge: 60 * 60 * 24 * 30, // 30 days
});
Reading Cookies in Loaders
import { json } from "@remix-run/node";
import { themeCookie } from "~/cookies.server";
export const loader = async ({ request }) => {
const theme = (await themeCookie.parse(request.headers.get("Cookie"))) || "light";
return json({ theme });
};
Setting Cookies in Actions
import { redirect, json } from "@remix-run/node";
import { themeCookie } from "~/cookies.server";
export const action = async ({ request }) => {
const formData = await request.formData();
const theme = formData.get("theme");
return json({ success: true }, {
headers: {
"Set-Cookie": await themeCookie.serialize(theme),
},
});
};
Cookie with Signed Values
import { createCookie } from "@remix-run/node";
export const preferencesCookie = createCookie("prefs", {
secrets: [process.env.COOKIE_SECRET],
maxAge: 60 * 60 * 24 * 30,
});
Remix signs cookie values when a secrets array is provided, preventing tampering.
Multiple Cookies in One Response
export const action = async ({ request }) => {
const theme = "dark";
const lang = "es";
const headers = new Headers();
headers.append("Set-Cookie", await themeCookie.serialize(theme));
headers.append("Set-Cookie", await languageCookie.serialize(lang));
return json({ success: true }, { headers });
};
Common Mistakes
- Not using
httpOnlyfor sensitive cookies: WithouthttpOnly, JavaScript can read the cookie, making it vulnerable to XSS Attacks. - Omitting
securein production: Setsecure: trueto ensure cookies are only sent over HTTPS. - Forgetting to parse cookies:
cookie.parse()returns the value. Without Parsing, you get the raw cookie string. - Setting cookies without
sameSite: Default islax, which is secure. SetsameSite: "none"only if cross-site requests need the cookie. - Using cookies for large data: Cookies are included in every request. Keep values under 4KB.
Practice Questions
How do you create a cookie in Remix? Answer: Use
createCookie("name", options)from@remix-run/node. Options includemaxAge,httpOnly,secure, andsameSite.How do you read a cookie in a loader? Answer: Parse it from the request header:
await cookie.parse(request.headers.get("Cookie")).How do you set a cookie in a response? Answer: Call
await cookie.serialize(value)and set it as aSet-Cookieheader on the response.What happens if a cookie doesn't have a
secretsarray? Answer: The value is stored as-is, without signing. Users can modify it. Usesecretsfor values that affect application behavior.
Challenge
Build a theme switcher that stores the preference in a cookie, reads it in the root loader, and applies the theme class to the HTML element. The preference should persist across sessions.
Mini Project
Create a cookie consent system: store consent in a signed cookie, show the banner only for new visitors, and allow users to update preferences later. The cookie should expire after 6 months.
FAQ
What's Next
Learn about Remix Authentication for implementing complete authentication systems.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro