🧑‍💻 JP

Creating and sending back cookies for Shopify Hydrogen Remix

By

John Phung

Shopify hydrogen session cookie

If you have been trying to create cookies server side following remix documentation, you may have come to understand that the same session methods actually come from shopify/remix-oxygen and not remix.

After some digging around Shopify support threads and documentation, there appears to be this utility function “createCookieSessionStorage” to create session cookies, as so:

1import { createCookieSessionStorage } from '@shopify/remix-oxygen';
2
3const {getSession, commitSession, destroySession} = createCookieSessionStorage(
4 {
5 cookie: {
6 name: "token",
7 httpOnly: true,
8 maxAge: 60,
9 path: "/",
10 sameSite: "lax",
11 secrets: ["yourownsecret"],
12 secure: true,
13 }
14 }
15 )
16
17export { getSession, commitSession, destroySession };

Let’s say for authentication reasons, I want to set a token in the cookie after successful login

1import {getSession, commitSession} from '/path/to/cookie';
2
3// example pulled from offical remix docs
4export async function action({
5 request,
6}: ActionFunctionArgs) {
7 const session = await getSession(
8 request.headers.get("Cookie")
9 );
10 const form = await request.formData();
11 const username = form.get("username");
12 const password = form.get("password");
13
14 const userId = await validateCredentials(
15 username,
16 password
17 );
18
19 if (userId == null) {
20 session.flash("error", "Invalid username/password");
21
22 // Redirect back to the login page with errors.
23 return redirect("/login", {
24 headers: {
25 "Set-Cookie": await commitSession(session),
26 },
27 });
28 }
29
30 session.set("userId", userId);
31
32 // Login succeeded, send them to the home page.
33 return redirect("/", {
34 headers: {
35 "Set-Cookie": await commitSession(session),
36 },
37 });
38}

What if I don’t want a redirect and just want to send data back? Sure, you can do a similar thing.

1return json(data, {
2 headers: {
3 "Set-Cookie": await commitSession(session),
4 },
5});

What if I want to set and send more than one cookie? Well that’s also simple.

You will need to create another cookie via createCookieSessionStorage, get the session, set the session, then commit the session. And for your headers, you will either need to append “Set-Cookie” multiple times or send back an array of headers.

Alternatively, you can combine all the properties you need into a single object and use a single cookie.

1const headers = new Headers()
2
3const session1 = await getSession1(request.headers.get("Cookie"))
4const session2 = await getSession2(request.headers.get("Cookie"))
5
6session1.set("token", token)
7session2.set("trustedDevice", Date.now())
8
9headers.append("Set-Cookie", await commitSession1(session1))
10headers.append("Set-Cookie", await commitSession2(session2))
11
12return json(data, {
13 headers,
14})