Store data in a cookie with sessions and Remix
6th July 2022In the last article, we looked at creating a simple cookie in Remix to determine whether the user was visiting for the first time, or a returning regular. This is great for boolean logic — where they either have or haven’t visited before — but if we want to store additional data in our cookie, we will need a session.
Let’s modify our previous example to not only track whether this is the user’s first time on the page, but count how many times they have visited. For this we are going to use Remix’s createCookieSessionStorage
function. Create a new file at app/utils/count-session.tsx
and populate with the following:
import { createCookieSessionStorage } from "@remix-run/node";
export const { getSession, commitSession, destroySession } =
createCookieSessionStorage({
cookie: {
name: "count-session",
},
});
createCookieSessionStorage
returns three functions for managing our session:
getSession
retrieves a session from a cookie stringcommitSession
creates a new cookie stringdestroySession
deletes session data and returns a cookie string
Let’s also create a new page at app/routes/count.tsx
and add the following:
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { getSession, commitSession } from "~/utils/count-session";
export const loader = async ({ request }: { request: Request }) => {};
const Count = () => {
const data = useLoaderData();
return <pre>{JSON.stringify(data, null, 2)}</pre>;
};
export default Count;
In our loader
function we want to:
-
Read the session from the cookie headers
const session = await getSession(request.headers.get("Cookie"));
-
Increment by 1 if exists, otherwise set to 1
const numberOfVisits: number = session.get("numberOfVisits") + 1 || 1;
-
Create a new cookie string
session.set("numberOfVisits", numberOfVisits); const cookie = await commitSession(session);
-
Return new value as response with updated cookie in headers
return json( { numberOfVisits }, { headers: { "Set-Cookie": cookie, }, } );
The full component should look something like this:
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { getSession, commitSession } from "~/utils/count-session";
export const loader = async ({ request }: { request: Request }) => {
// Read session from cookie
const session = await getSession(request.headers.get("Cookie"));
// Increment by 1 if exists, otherwise set to 1
const numberOfVisits: number = session.get("numberOfVisits") + 1 || 1;
// Create new cookie string
session.set("numberOfVisits", numberOfVisits);
const cookie = await commitSession(session);
// Set new cookie in headers
return json(
{ numberOfVisits },
{
headers: {
"Set-Cookie": cookie,
},
}
);
};
const Count = () => {
const data = useLoaderData();
return <pre>{JSON.stringify(data, null, 2)}</pre>;
};
export default Count;
And that’s it! 🎉
If you navigate to http://localhost:3000/count and refresh a few times you should see the numberOfVisits
value incrementing by 1 each time.
{
"numberOfVisits": 404
}
Thanks for reading! 🙌 While you’re waiting for next week’s article, why not follow me on Twitter!