Used

How toDestroy User Session and While Setting a Flash Message in React Router

The session API from React Router lets us set flash messages that we can read only once. Doing this helps display a message to the user after an action. But what if the action destroys the session in the process, like a logout?

How we achieve it depends on your session storage mechanism.

If you use the cookie session storage, the session data is stored entirely in the cookie value. Here, we can create a new session by calling sessionStorage.getSession() without passing the cookie header value. Doing this will make a new session, and we can set the flash message and commit the session to the user, essentially destroying the previous session.

import type { Route } from "./+types/logout";
import { redirect } from "react-router";

export async function action() {
  // don't pass request.headers.get("cookie") here
  let session = await sessionStorage.getSession();

  // and set the flash message
  session.flash("success", "You have been logged out");

  // and commit the session while sending a response
  return redirect("/", {
    headers: { "Set-Cookie": await sessionStorage.commitSession(session) },
  });
}

If you use another session storage, your cookie will contain a sessionId, and the session data will be stored somewhere else, like in a database. In this case, you can get the current session, destroy it, and generate a new one.

import type { Route } from "./+types/logout";
import { redirect } from "react-router";

export async function action() {
  // get the current session
  let session = await sessionStorage.getSession(request.headers.get("cookie"));

  // and destroy it here
  await sessionStorage.destroySession(session);

  // then create a new session
  let newSession = await sessionStorage.getSession();

  // and set the flash message
  newSession.flash("success", "You have been logged out");

  // and commit the session while sending a response
  return redirect("/", {
    headers: { "Set-Cookie": await sessionStorage.commitSession(newSession) },
  });
}