SvelteKit fetch with SanityClient without losing credentials

5 replies
Last updated: Feb 15, 2022
How would I replace the
fetch
function used by
SanityClient
without loosing the credentials? I'm using sveltekit which come with its own implementation of
fetch
for use in load functions (a specific function that runs before the page is rendered). Will I lose my credentials if I do
sanity.fetch = fetch
, having that sveltkit
fetch
available in the current context?
AI Update

Great question! The short answer is: no, you won't lose your credentials by passing SvelteKit's fetch to the Sanity client, but there's a better approach that's recommended.

When you do sanity.fetch = fetch or use SvelteKit's fetch directly with the Sanity client, you're actually enhancing the functionality rather than breaking it. SvelteKit's special fetch implementation (available in load functions) provides benefits like:

  • Automatic cookie forwarding
  • Request deduplication during SSR
  • Proper tracking of dependencies

Your Sanity credentials (API tokens, project ID, dataset) are typically passed through headers or configuration options, not embedded in the fetch function itself. So swapping the fetch implementation won't strip those credentials away.

However, based on Sanity's documentation, the better approach is to create a SvelteKit endpoint that wraps your Sanity client calls. Here's why:

  1. Security: Load functions run on both client and server. If you're using authenticated/credentialed requests (like with a read token for private data), you don't want those credentials exposed to the client
  2. Better architecture: Keeps your API tokens server-side only
  3. Cleaner code: With modern SvelteKit, you can use the endpoint pattern where files like +page.server.js automatically provide data to their corresponding +page.svelte

Implementation Example

Instead of using the Sanity client directly in your load function:

// +page.server.js
import { client } from '$lib/sanity'

export async function load({ fetch }) {
  // This works but exposes credentials if you're using tokens
  const data = await client.fetch(query)
  return { data }
}

Create an endpoint and use SvelteKit's fetch:

// +page.server.js
export async function load({ fetch }) {
  const response = await fetch('/api/content')
  const data = await response.json()
  return { data }
}

// routes/api/content/+server.js
import { client } from '$lib/sanity'
import { json } from '@sveltejs/kit'

export async function GET() {
  const data = await client.fetch(query)
  return json(data)
}

With newer SvelteKit versions, if your endpoint has the same filename as your page (minus the extension), the page automatically gets props from the endpoint without you needing to explicitly fetch.

When Direct Usage is Fine

If you're only querying public data (no read tokens, using the public API), then directly passing SvelteKit's fetch to your Sanity client is perfectly safe:

import { createClient } from '@sanity/client'

export async function load({ fetch }) {
  const client = createClient({
    projectId: 'your-project',
    dataset: 'production',
    apiVersion: '2023-05-03',
    useCdn: true,
    fetch // SvelteKit's fetch
  })
  
  const data = await client.fetch(query)
  return { data }
}

Your credentials (project ID, dataset) are still intact—you're just giving the client a different fetch implementation to use under the hood.

Show original thread
5 replies
I usually put the sanity client into an endpoint & use sveltekit's fetch to hit that endpoint, a bit cumbersome but if you're on the latest svelte kit, they remove some of that boilerplate: https://kit.svelte.dev/docs/routing#endpoints

If an endpoint has the same filename as a page (except for the extension), the page will get its props from the endpoint. So a page like 
src/routes/items/[id].svelte
 could get its props from `src/routes/items/[id].js`:
Also load function will run on the client as well, so it's not a good idea to run credential'd requests there I think (unless that's exactly what you want to do 😅 )
Thanks, you put me on the right rails 😉
user G
With the latest sveltekit, I'm getting the result in my endpoint as a
prop
, accessible in the load function of an associated page. Does this means sveltekit is using their special
fetch
to hit the
get
endpoint behind the scenes, and that I can use that prop directly without hitting the endpoint with fetch myself (in my case just directly return it to make it available to my page)?
Yes that's right, if the load function in your page is doing nothing but fetching that data from an endpoint, you can remove it (note that if you're naming your endpoint something like
[page].json.js
, you have to remove the
.json
)

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?