Skip to content

Remix Sessions — Managing User Sessions

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Remix Sessions. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Remix sessions: create session storage, read/write session data, implement flash messages, and manage authentication state across requests.

In this lesson, you'll implement session management using Remix's session APIs, storing session data in cookies or external storage.

What You'll Learn

How to create session storage, read and write session data, use flash messages for one-time notifications, and implement login sessions.

Why It Matters

Sessions enable user authentication, temporary data storage across requests, and flash messages for user feedback after form submissions.

Real-World Use

DodaZIP uses sessions for user authentication tokens, temporary form state, and flash messages after CRUD operations.

flowchart LR
    A[Request] --> B[Session Load]
    B --> C[Read Data]
    C --> D[Modify Data]
    D --> E[Commit Session]
    E --> F[Response with Cookie]
    style B fill:#121212,color:#fff

Session Storage

Create session configuration:

// app/session.server.ts
import { createCookieSessionStorage } from "@remix-run/node";

const { getSession, commitSession, destroySession } =
  createCookieSessionStorage({
    cookie: {
      name: "__session",
      httpOnly: true,
      maxAge: 60 * 60 * 24 * 7, // 1 week
      path: "/",
      sameSite: "lax",
      secrets: [process.env.SESSION_SECRET],
      secure: process.env.NODE_ENV === "production",
    },
  });

export { getSession, commitSession, destroySession };

Reading and Writing Sessions

Use sessions in loaders and actions:

import { getSession, commitSession } from "~/session.server";

export const action = async ({ request }) => {
  const session = await getSession(request.headers.get("Cookie"));
  
  // Read session data
  const visits = session.get("visits") || 0;
  
  // Write session data
  session.set("visits", visits + 1);
  session.set("lastVisit", new Date().toISOString());
  
  return json({ visits: visits + 1 }, {
    headers: {
      "Set-Cookie": await commitSession(session),
    },
  });
};

Flash Messages

One-time notifications that disappear after reading:

// Setting a flash message
session.flash("success", "User created successfully!");

// Reading a flash message (removed after read)
const message = session.get("success");

Flash messages are perfect for "Item saved" or "Error occurred" notifications after form submissions.

Login Session

Implement a simple login session:

export const action = async ({ request }) => {
  const formData = await request.formData();
  const session = await getSession(request.headers.get("Cookie"));
  
  const user = await authenticateUser(formData.get("email"), formData.get("password"));
  
  if (user) {
    session.set("userId", user.id);
    session.set("role", user.role);
    
    return redirect("/dashboard", {
      headers: { "Set-Cookie": await commitSession(session) },
    });
  }
  
  session.flash("error", "Invalid credentials");
  return json({ error: "Invalid credentials" }, {
    headers: { "Set-Cookie": await commitSession(session) },
  });
};

Destroying Sessions

Logout by destroying the session:

export const action = async ({ request }) => {
  const session = await getSession(request.headers.get("Cookie"));
  
  return redirect("/login", {
    headers: { "Set-Cookie": await destroySession(session) },
  });
};

Common Mistakes

  1. Not committing the session after changes: session.set() doesn't persist until commitSession() is called and the cookie header is set.
  2. Forgetting httpOnly and secure flags: Sessions should be httpOnly (inaccessible to JavaScript) and secure in production.
  3. Using session for large data: Sessions are sent with every request. Keep session data small. Use a database for large datasets.
  4. Not rotating session secrets: Rotate SESSION_SECRET periodically and support multiple secrets for smooth transitions.
  5. Exposing session data in error responses: Session data should not appear in error messages returned to the client.

Practice Questions

  1. What does createCookieSessionStorage create? Answer: A session storage that stores session data in encrypted cookies. Returns getSession, commitSession, and destroySession.

  2. How do you add data to a session? Answer: Call session.set("key", value). Commit the session with commitSession() and set the Set-Cookie header.

  3. What is a flash message? Answer: A one-time session value that's automatically removed after being read. Useful for success/error notifications after form posts.

  4. How do you log a user out? Answer: Destroy the session with destroySession() and set the Set-Cookie header to clear the session cookie.

Challenge

Implement a complete authentication system with login, session-based auth, protected routes that check session data, and logout functionality.

Mini Project

Build a session-based shopping cart: add items to cart (stored in session), view cart, update quantities, and clear cart on checkout. Include flash messages for "Item added" notifications.

FAQ

Can I use database-backed sessions instead of cookies?

: Yes. Use createSessionStorage() with a custom store parameter to back sessions with Redis, PostgreSQL, or any database.

What is the session data size limit?

: Cookie sessions are limited to 4KB. For larger data, use database-backed sessions.

Can I have multiple session cookies?

: Yes. Create separate session storages with different cookie names for different purposes.

How do I handle session expiration?

: Set maxAge in the cookie options. The browser deletes the cookie after expiration.

What's Next

Learn about Remix Cookies for direct cookie manipulation without session abstractions.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro