sveltejs / sveltejs/kit

Expose `add_cookies_to_headers` via `cookies.write`

Open
#11,712 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
20.8k
Forks
2.3k
Avg merge
1d 16h
Merged PRs (30d)
156

Description

Describe the problem

This has been discussed before in #8409 and #7611, but I think we have a bit of a different use case here.

We're working on a cookie manager library that layers on some additional niceties to the cookies API in SvelteKit (e.g. defining and validating the shape of cookies, handling serializing to/from JSON and base64, ability to manage and write cookies both server side and client side, etc). The manager allows libraries to define their own cookies and then export them, so you can have shared cookies between different libraries more easily:

export const cookieManager = new SvelteKitCookieManager({
  deviceId: {
    key: 'device_id',
    validator: (z) => z.string(),
  }
});

// Usage
cookieManager.getWriter('server', event).get('deviceId');
cookieManager.getWriter('server', event).set('deviceId', 'foo');

This is all typed and really nice to work with. The tricky part is that we can't really use it in both hooks and +page.server.ts contexts, because in hooks we can't use the cookies API, but in +page.server.ts we must use the cookies API, there's no way for us to add set-cookies headers otherwise. Currently it seems like the only option is to have a new type of writer or some other option for changing the behavior in hooks vs pages.

cookieManager.getWriter('server', event.cookies).get('deviceId');
cookieManager.getWriter('server-hooks', event.headers.get('cookie')).set('deviceId', 'foo');
Describe the proposed solution

I feel like this could be remedied by exposing the add_cookies_to_headers function on the cookies API. This would only be callable once per request, it would throw if called a second time. The purpose would be so that hooks that return custom responses can optionally choose to write out the added cookies manually at some point.

Alternatives considered

We could allow users to add the set-cookie header via the headers API. Our library currently outputs the set-cookie value as a string, so it would be easy to add it that way, but it does seem a bit hacky.

We could also always serialize cookies to all responses, but this would be tricky. I think there are a couple ways to approach this:

  1. Serialize cookies at the end of hooks. As noted in #7611 this would result in a gap between cookies being added and hooks resolving, so hooks would no longer see any added cookies. This would also be a breaking API change so probably not worth it.
  2. Add cookies at the end of handle IFF they have not been added by resolve (e.g. resolve has not been called). Throw an error otherwise. This would work well, but would mean that users can't call resolve, ignore the response, and then set cookies, which would be a weird edge case.
  3. Add cookies twice, once at the end of resolve and once at the end of handle. Set cookies would be cleared in between so they don't set twice, just new ones would be added the second time. This would allow the API to be used in all cases and allow resolve cookies to be ignored by hooks, but would be more complex and require some additional bookkeeping to flush the cookies between sets.
Importance

nice to have

Additional Information

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the cookies API and the hooks/resolve response flow described in the issue, then review discussions #8409 and #7611 for prior constraints. The work is done when a caller can invoke add_cookies_to_headers through cookies.write once for a custom response, with a second invocation rejected, and the behavior is covered by relevant tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.