How to Use Cookie Session in Remix for User Sessions
In Remix, use
createCookieSessionStorage from @remix-run/node to create a cookie-based session storage. Configure the cookie options, then use the session storage methods to get, commit, and destroy sessions in your loaders and actions.Syntax
The main function to create cookie sessions in Remix is createCookieSessionStorage. It takes a configuration object with a cookie property that defines cookie settings like name, secrets, secure, and sameSite.
Use the returned storage object to call getSession(request.headers.get('Cookie')) to read a session, commitSession(session) to save changes, and destroySession(session) to clear it.
typescript
import { createCookieSessionStorage } from '@remix-run/node'; const storage = createCookieSessionStorage({ cookie: { name: 'session', secrets: ['your-secret-key'], secure: process.env.NODE_ENV === 'production', sameSite: 'lax', path: '/', maxAge: 60 * 60 * 24 * 7, // 7 days httpOnly: true } }); // Usage in loaders or actions export async function loader({ request }) { const session = await storage.getSession(request.headers.get('Cookie')); // read or write session data return new Response('OK', { headers: { 'Set-Cookie': await storage.commitSession(session) } }); }
Example
This example shows a simple Remix loader and action using cookie session to count page visits. The loader reads the session count, increments it, and commits the updated session cookie in the response.
typescript
import { createCookieSessionStorage } from '@remix-run/node'; const sessionStorage = createCookieSessionStorage({ cookie: { name: 'visit_session', secrets: ['super-secret-key'], secure: process.env.NODE_ENV === 'production', sameSite: 'lax', path: '/', httpOnly: true } }); export async function loader({ request }) { const cookie = request.headers.get('Cookie'); const session = await sessionStorage.getSession(cookie); let visitCount = session.get('count') || 0; visitCount++; session.set('count', visitCount); return new Response(`You have visited this page ${visitCount} times.`, { headers: { 'Set-Cookie': await sessionStorage.commitSession(session) } }); }
Output
You have visited this page 1 times.
Common Pitfalls
- Not setting
secrets: The cookie session requires a secret key to sign cookies securely. Forgetting this causes errors or insecure cookies. - Using
secure: truein development: This prevents cookies from being set on localhost without HTTPS. Usesecure: process.env.NODE_ENV === 'production'to avoid this. - Forgetting to commit the session: Changes to the session are not saved unless you call
commitSessionand set theSet-Cookieheader in the response. - Not reading the cookie header correctly: Always pass
request.headers.get('Cookie')togetSessionto load the session.
typescript
/* Wrong: Missing secrets and always secure */ const badStorage = createCookieSessionStorage({ cookie: { name: 'bad', secure: true // breaks on localhost } }); /* Right: Include secrets and conditional secure */ const goodStorage = createCookieSessionStorage({ cookie: { name: 'good', secrets: ['secret'], secure: process.env.NODE_ENV === 'production' } });
Quick Reference
- createCookieSessionStorage(config): Creates session storage with cookie options.
- getSession(cookieHeader): Reads session from cookie header.
- commitSession(session): Returns a cookie header string to save session.
- destroySession(session): Returns a cookie header string to clear session.
Key Takeaways
Use createCookieSessionStorage with proper cookie options including secrets to manage sessions.
Always read the cookie header from the request and commit session changes in the response.
Set secure flag conditionally to avoid issues in development environments.
Use httpOnly and sameSite cookie options for better security.
Remember to destroy sessions explicitly when logging out users.