Skip to content

Make it possible to return more than JSON from server-only load functions #6008

@Rich-Harris

Description

@Rich-Harris

Describe the problem

Right now, the output of load in +layout.server.js or +page.server.js has to be serialized with JSON.stringify so that it can be transported to the client.

Occasionally it's useful to transport values that can't be serialized as JSON. Date springs to mind, along with things like this, where anything expecting selected to be a member of options post-deserialization will be disappointed:

export function load() {
  const options = [
    { flavour: 'chocolate' },
    { flavour: 'strawberry' },
    { flavour: 'banana' }
  ];

  const selected = options[0];

  return { options, selected };
}

Describe the proposed solution

We have a proven technique for this: https://github.com/rich-harris/devalue. It's fast, and doesn't involve a deserialization step. (It doesn't currently support BigInt though, we'd need to add that.)

To work with CSP, we can't eval the result (including by creating a <script>), we need to import it. Since we need to get fresh data when navigating back to a previously-visited page, we need to use a cachebusting mechanism; since modules live in a cache that we have no way of purging, we need to be careful to avoid memory leaks.

We can't therefore do this...

export const data = {...};

...and must instead do this, so that the data can be garbage collected once it's been used:

window.__data = {...};

On the client side, it would look something like this:

let uid = 1;

// later
await import(`${url.pathname}/__data.js`);
const data = window.__data;
delete window.__data;

Alternatives considered

There's a variety of alternatives to devalue listed here: https://github.com/rich-harris/devalue#see-also, though I'm not aware of any reasons to favour them.

Or, we could just stick to JSON, which has better performance characteristics if you have a huge amount of data.

Importance

nice to have

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature / enhancementNew feature or requestp2-nice-to-haveSvelteKit cannot be used by a small number of people, quality of life improvements, etc.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions