sveltejs / sveltejs/kit

Remote functions incorrectly send full response to client when used in server loads

Open
#14,449 0 comments 4 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 bug

When using a remote function within a server load, the entire payload of the remote function is sent to the client, no matter which properties you actually intend to send.

This probably isn't a security issue, as generally remote functions are called from the client anyway, but it could be unwanted behavior and could expose data that wasn't supposed to be exposed.

In my situation, I simply wanted to reuse the same remote function but only expose a handful of properties instead of the full payload.

Here's a setup:

// query.remote.ts
import { query } from "$app/server";

export const getSomeData = query(async () => {
  return { message: "Hello!", bigData: "x".repeat(10000) };
});
// +page.server.ts
import { getSomeData } from '$lib/query.remote';
import type { PageServerLoad } from './$types';

export const load = (async () => {
    const data = await getSomeData();

    return {
        message: data.message,
    };
}) satisfies PageServerLoad;
+page.svelte (slightly longer but basically does nothing)
<script lang="ts">
  import { onMount } from "svelte";
  import type { PageProps } from "./$types";

  let { data }: PageProps = $props();

  let scriptContent = $state("");

  onMount(() => {
    // Select the script tag in the body
    const scriptTag = document.querySelector("script");
    scriptContent = (scriptTag?.innerHTML || "");
  });
</script>

<h1>Welcome to SvelteKit</h1>
<p>
  Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the
  documentation
</p>

<p>{data.message}</p>

<p>Check the HTML for "bigData" that has a ton of x's repeated. This wasn't supposed to be sent to the client.</p>


<p>Contents of script tag:</p>
<p>{scriptContent}</p>

Despite only passing down message, the full payload is sent to the client and can be seen in the HTML. The attached reproduction shows the contents of the script tag that sveltekit generates, and you can see the 10,000 "x"s in the html:

Image
Expected Behavior

I thought using remote functions on the server like this would just grab the data being returned like a normal function call. For the example, the page server load should effectively behave like this:

export const load = (async () => {
    const data = { message: "Hello!", bigData: "x".repeat(10000) };

    return {
        message: data.message,
    };
}) satisfies PageServerLoad;

Which, as expected, only sends message to the client.

Reproduction

Reproduction:
remote-functions-in-load.zip
or
https://stackblitz.com/edit/sveltejs-kit-template-default-5uwyw2aw?file=src%2Flib%2Fquery.remote.ts

Simply load the main page to see that the full response is sent to the client, even though only message was passed down.

Logs

System Info
System:
    OS: Windows 10 10.0.19045
    CPU: (16) x64 AMD Ryzen 7 9800X3D 8-Core Processor
    Memory: 3.44 GB / 31.16 GB
  Binaries:
    Node: 24.6.0 - C:\nvm4w\nodejs\node.EXE
    Yarn: 1.22.22 - C:\nvm4w\nodejs\yarn.CMD
    npm: 11.5.1 - C:\nvm4w\nodejs\npm.CMD
    pnpm: 10.15.0 - C:\nvm4w\nodejs\pnpm.CMD
  Browsers:
    Edge: Chromium (140.0.3485.54)
    Internet Explorer: 11.0.19041.5794
  npmPackages:
    @sveltejs/adapter-auto: ^6.0.0 => 6.1.0
    @sveltejs/kit: ^2.22.0 => 2.42.1
    @sveltejs/vite-plugin-svelte: ^6.0.0 => 6.2.0
    svelte: ^5.0.0 => 5.38.10
    vite: ^7.0.4 => 7.1.5
Severity

annoyance

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 by running the linked reproduction and inspect query.remote.ts, +page.server.ts, and the generated script from +page.svelte. Trace how a remote function called during a server load is serialized into page data. Done means the page still receives message while bigData is absent from the client HTML, with regression coverage for this case.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.