Managing Cookies

Avatar of Hemanta SundarayHemanta Sundaray

By default, HttpClient doesn’t track cookies between requests. Each request is independent. If you need cookie persistence — for example, to maintain a session after logging in — you can use HttpClient.withCookiesRef().

withCookiesRef associates a Ref<Cookies> with the client. The client will automatically extract Set-Cookie headers from responses and include the stored cookies in subsequent requests.

http.ts
import {
FetchHttpClient,
HttpClient,
HttpClientRequest,
Cookies,
} from "effect/unstable/http";
import { Effect, Ref } from "effect";
function sessionExample() {
return Effect.gen(function* () {
// Create a mutable Ref to hold cookies
const cookieRef = yield* Ref.make(Cookies.empty);
const client = (yield* HttpClient.HttpClient).pipe(
HttpClient.withCookiesRef(cookieRef),
);
// Step 1: Log in — the server sets session cookies
const loginRequest = HttpClientRequest.post(
"https://dummyjson.com/auth/login",
).pipe(
HttpClientRequest.bodyJsonUnsafe({
username: "emilys",
password: "emilyspass",
}),
);
yield* client.execute(loginRequest);
// Step 2: Check what cookies were stored
const cookies = yield* Ref.get(cookieRef);
console.log("Stored cookies:", cookies);
// Step 3: Subsequent requests automatically include the cookies
const meResponse = yield* client.get("https://dummyjson.com/auth/me");
const user = yield* meResponse.json;
return user;
}).pipe(Effect.provide(FetchHttpClient.layer));
}
// Test it
Effect.runPromise(sessionExample()).then(
(user) => console.log("User:", user.firstName, user.lastName),
(error) => console.error("Error:", error),
);

Output:

Terminal
Stored cookies: {
_id: 'effect/Cookies',
cookies: {
accessToken: {
_id: 'effect/Cookies/Cookie',
name: 'accessToken',
value: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJlbWlseXMiLCJlbWFpbCI6ImVtaWx5LmpvaG5zb25AeC5kdW1teWpzb24uY29tIiwiZmlyc3ROYW1lIjoiRW1pbHkiLCJsYXN0TmFtZSI6IkpvaG5zb24iLCJnZW5kZXIiOiJmZW1hbGUiLCJpbWFnZSI6Imh0dHBzOi8vZHVtbXlqc29uLmNvbS9pY29uL2VtaWx5cy8xMjgiLCJpYXQiOjE3NzE1ODEzMTAsImV4cCI6MTc3MTU4NDkxMH0.oP3Sgp0kDaJx1YIK7RWSd6R5vOeVsxZn_VQhKMrJYdw',
options: [Object]
},
refreshToken: {
_id: 'effect/Cookies/Cookie',
name: 'refreshToken',
value: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJlbWlseXMiLCJlbWFpbCI6ImVtaWx5LmpvaG5zb25AeC5kdW1teWpzb24uY29tIiwiZmlyc3ROYW1lIjoiRW1pbHkiLCJsYXN0TmFtZSI6IkpvaG5zb24iLCJnZW5kZXIiOiJmZW1hbGUiLCJpbWFnZSI6Imh0dHBzOi8vZHVtbXlqc29uLmNvbS9pY29uL2VtaWx5cy8xMjgiLCJpYXQiOjE3NzE1ODEzMTAsImV4cCI6MTc3NDE3MzMxMH0.xk7nJYPVBFoCYKuyEJSE3k4m8soWgHvJ0z_uuvpYgKU',
options: [Object]
}
}
}
User: Emily Johnson

Here’s how the flow works:

  1. You create a Ref<Cookies> initialized with Cookies.empty.
  2. You attach it to the client with withCookiesRef.
  3. On every subsequent request, the client reads the Ref and attaches the stored cookies as a Cookie header.

The Ref is mutable and shared. If you use the same Ref with multiple clients (or the same client across multiple requests), they all share the same cookie jar.

You can also inspect or modify the cookies at any time using Ref.get and Ref.set. This is useful for debugging or for manually injecting cookies that weren’t set by a server response.

Sign in to save progress

Stay in the loop

Get notified when new chapters are added and when this course is complete.