kit: Cannot use relative URL with global fetch in .svelte file

Describe the bug

According to the documentation, I should be able to create an endpoint in a +server.js file and call that endpoint with a relative url via fetch from +page.svelte (https://kit.svelte.dev/docs/routing#server-receiving-data).

This is not possible anymore. I get an error message that was introduced with https://github.com/sveltejs/kit/pull/8370 :

Cannot use relative URL (<relative-url>) with global fetch — use `event.fetch` instead: https://kit.svelte.dev/docs/web-standards#fetch-apis

Hower, the referenced documentation does not even mention event.fetch and also does not explain why this is not possible in .svelte files.

Reproduction

The example of https://kit.svelte.dev/docs/routing#server-receiving-data .

Logs

Server Log:

Error: Cannot use relative URL (/search?query=) with global fetch — use `event.fetch` instead: https://kit.svelte.dev/docs/web-standards#fetch-apis
    at globalThis.fetch (file:///<path>/node_modules/@sveltejs/kit/src/exports/vite/dev/index.js:35:10)
    at getSearchResult (/src/routes/search/+layout.svelte:12:26)
    at Timeout.eval [as _onTimeout] (/src/routes/search/+layout.svelte:30:11)
    at listOnTimeout (node:internal/timers:564:17)
    at process.processTimers (node:internal/timers:507:7)


### System Info

```Shell
OS: Windows 10 10.0.22621
    CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor
    Memory: 8.86 GB / 31.93 GB
  Binaries:
    Node: 18.12.1 - C:\Program Files\nodejs\node.EXE
    npm: 8.19.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.22621.1105.0), Chromium (108.0.1462.76)
    Internet Explorer: 11.0.22621.1

Severity

blocking an upgrade

Additional Information

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 12
  • Comments: 16 (7 by maintainers)

Commits related to this issue

Most upvoted comments

I had this same problem and just didn’t understand. It seems like the conversation was over my head. The error message says ‘use event.fetch instead’ and the linked page never references ‘event’. The parameter passed to ‘load()’ is actually event, but all the examples I’ve seen use destructuring and I didn’t know the parameter was called ‘event’, or that it had a ‘fetch’ property since I had only seen ‘params’ destructured (i.e. event.params). I believe this is what using ‘event.fetch’ means:

export async function load({ params, fetch }) { // <--- event.params and event.fetch
  fetch('/realative/url') // parameter hides normal fetch() function
}

As I load the data initially with PageServerLoad (https://kit.svelte.dev/docs/load#page-data), I for my part do not need to do a fetch in a svelte component while it is rendered server side. But I do need to do a fetch later on, which will only be on client side. My solution was to wrap it with the browser environment variable from sveltekit.

import { browser } from "$app/environment";

if (browser) {
  const res = await fetch(
    // url
  );
  data = await res.json();
}

With this I did not get the error “Cannot use relative URL (…) with global fetch”.

Just writing it as this may help some others reading this.

how to fetch in the load function is described here: https://kit.svelte.dev/docs/load#making-fetch-requests

I loaded a small set of items via page.js and then tried to load more on intersecting when i run in to this error. edit: it worked well while just intersecting. but then i added a filter section (filter acts on +server.js) it was working when klicking the navbar link, but not on page reload

import { browser } from "$app/environment";

if (browser) {
  const res = await fetch(
    // url
  );
  data = await res.json();
}

This was the solution for me as well, thank you Zerdayne

@kegesch judging from the code snippet this could never have worked, you would have gotten a different error (which is generic and therefore we added a more descriptive error in #8370), but you would have gotten an error.

@amr3k your case is interesting. Using {#await ..} like that on the server does swallow the error, which is why it worked for you before - but probably not the way you expected it. On the server, {#await ..} is not actually awaited, instead you fire off a request which is ignored (or in your case, previously errored because the URL is invalid).

Both of your use cases sound like you maybe are not interested in server side rendering at all? In this case you can turn your SvelteKit app into an SPA by adding export const ssr = false to a root +layout.js file.

I had this same problem and just didn’t understand. It seems like the conversation was over my head. The error message says ‘use event.fetch instead’ and the linked page never references ‘event’. The parameter passed to ‘load()’ is actually event, but all the examples I’ve seen use destructuring and I didn’t know the parameter was called ‘event’, or that it had a ‘fetch’ property since I had only seen ‘params’ destructured (i.e. event.params). I believe this is what using ‘event.fetch’ means:

export async function load({ params, fetch }) { // <--- event.params and event.fetch
  fetch('/realative/url') // parameter hides normal fetch() function
}

is this fixed? or is it on different issue since this issue is closed