Skip to content

docs/ts: document cookie support #1939

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/menu.cue
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,11 @@
text: "Static Assets"
path: "/ts/primitives/static-assets"
file: "ts/primitives/static-assets"
}, {
kind: "basic"
text: "Cookies"
path: "/ts/primitives/cookies"
file: "ts/primitives/cookies"
}]
}, {
kind: "basic"
Expand Down
187 changes: 187 additions & 0 deletions docs/ts/primitives/cookies.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
---
seotitle: Using Cookies in Encore.ts API Endpoints
seodesc: Learn how to work with cookies in your TypeScript backend applications built with Encore.ts
title: Working with Cookies
subtitle: Type-safe cookie handling for web applications
lang: ts
---

Encore.ts provides type-safe cookie handling for your API endpoints. Cookies are commonly used for session management, personalization, and tracking. This guide explains how to use cookies in different contexts within your Encore.ts application.

## Where Cookies Can Be Used

Cookies can be utilized in three main contexts within Encore.ts:

1. **Auth handler parameters**: Access cookies during authentication
2. **Response cookies**: Set cookies to be sent back to clients
3. **Request cookies**: Access cookies sent by clients

## Using Cookies in Auth Handlers

Cookies can be used in authentication handlers:

```ts
import { Cookie, Gateway } from "encore.dev/api";
import { authHandler } from "encore.dev/auth";

// Define auth parameters with cookies
interface AuthParams {
sessionId: Cookie<"sessionId">;
}

// Auth handler that uses cookies
const auth = authHandler<AuthParams, User>(async ({ sessionId }) => {
return validateAndGetUser(sessionId.value);
});

// Configure the gateway with the auth handler
export const gateway = new Gateway({
authHandler: auth,
});
```

## Setting Cookies in Responses

You can set cookies in your API responses by including them in your response type:

```ts
import { api, Cookie } from "encore.dev/api";

// Define a response type with a cookie
interface LoginResponse {
user: UserData;
sessionId: Cookie<"sessionId">;
}

// Create an API endpoint that sets a cookie
export const login = api<LoginParams, LoginResponse>({
method: "POST",
path: "/login",
expose: true,
}, async (params): Promise<LoginResponse> => {
// Authenticate user
const user = await authenticateUser(params.username, params.password);
const sessionId = generateSessionId();

// Store session
await storeSession(sessionId, user.id);

// Return response with cookie
return {
user,
sessionId: {
value: sessionId,
httpOnly: true,
secure: true,
sameSite: "Strict",
maxAge: 60 * 60 * 24 * 7, // 7 days
}
};
});
```

## Using Cookies in Requests

When creating API endpoints, you can access cookies sent by the client by defining them in your parameter type:

```ts
import { api } from "encore.dev/api";

// Define a request type with a cookie
interface Params {
language?: Cookie<"language">;
}

// Create an API endpoint that uses the cookie
export const get = api<Params, { msg: string }>(
{
method: "GET",
path: "/user/profile",
expose: true,
},
async ({ language }) => {
// Access the cookie value
const lang = language?.value ?? "en";
return { msg: `your language: ${lang}` };
},
);```

## Typed Cookie Values

Encore.ts allows you to specify the type of cookie values for improved type safety. By default, cookie values are strings, but you can define cookies with different data types. If you omit the type parameter, Encore.ts will automatically use `string` as the type.

### Available Cookie Types

You can use the following types for cookie values:

- `string`: Text data (default when generic parameter is omitted)
- `number`: Numeric values
- `boolean`: True/false values
- `Date`: Date objects

### How to Specify Cookie Types

When defining cookies, you can specify the type using the generic parameter:

```ts
interface UserPreferences {
// Cookies with different types
userId: Cookie<number, "userId">;
darkMode: Cookie<boolean, "darkMode">;
lastVisit: Cookie<Date, "lastVisit">;
language: Cookie<string, "language">;
// Using omitted type parameter (implicitly string)
theme: Cookie<"theme">;
}

export const savePreferences = api<UserPreferences, void>({
method: "POST",
path: "/user/preferences",
expose: true,
}, async (params) => {
// Type-safe access to cookie values
const userId = params.userId.value; // number
const isDarkMode = params.darkMode.value; // boolean
const lastVisit = params.lastVisit.value; // Date
const language = params.language.value; // string
const theme = params.theme.value; // string (implicitly typed)

// Save preferences...
});
```

## Cookie Options

When setting cookies, you can configure various options:

- **expires**: Sets an expiration date
- **maxAge**: Sets the cookie lifetime in seconds
- **domain**: Specifies which domains can receive the cookie
- **path**: Limits the cookie to a specific path
- **secure**: Only sends the cookie over HTTPS
- **httpOnly**: Makes the cookie inaccessible to JavaScript
- **sameSite**: Controls when cookies are sent with cross-site requests
- `"Strict"`: Only sent in same-site requests
- `"Lax"`: Sent with same-site requests and top-level navigations
- `"None"`: Sent with all requests (requires `secure: true`)
- **partitioned**: Creates a partitioned cookie using the CHIPS model

## Generated client

The generated Encore.ts client does not explicitly handle cookies. Instead, it relies on the browser's built-in cookie handling. When using the client in browser environments, cookies will be automatically included in requests and stored from responses.

For cross-site requests, you need to configure the client to include credentials:

```ts
// Create a client that includes credentials (cookies) for cross-site requests
const client = new Client(Local, { requestInit: { credentials: "include" } });
```

## Best Practices

1. Use `httpOnly: true` for cookies containing sensitive data
2. Set `secure: true` for production environments
3. Configure appropriate `sameSite` settings based on your requirements
4. Use the `maxAge` or `expires` options to limit cookie lifetime

By following these guidelines, you can effectively leverage cookies in your Encore.ts applications while maintaining security and type safety.
16 changes: 16 additions & 0 deletions docs/ts/primitives/defining-apis.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,22 @@ export const getBlogPost = api(
)
```

### Cookie parameters

Cookies are defined by setting the field type to `Cookie<"Name-Of-Cookie">`. It can be used in both request and response data types.

In the example below we define an optional field that will be parsed from the cookie header.

```ts
import { Cookie } from "encore.dev/api";

interface Params {
settings?: Cookie<"settings">; // parsed from cookie header
}
```

Read more about cookies [here](/docs/ts/primitives/cookies)

### Fallback routes

Encore supports defining fallback routes that will be called if no other endpoint matches the request,
Expand Down
Loading