Sanity Client 403 Error in SvelteKit with Flashing Content
The 403 error you're seeing in your SvelteKit project is almost certainly a CORS (Cross-Origin Resource Sharing) configuration issue. The fact that content "flashes" briefly suggests your query works initially server-side, but fails when SvelteKit tries to re-fetch it client-side.
The Problem
SvelteKit's default behavior is to run load functions on both the server (SSR) and client (browser). The server-side fetch works fine, but when the page hydrates or navigates client-side, the browser makes a direct request to Sanity's API - and that's where CORS restrictions kick in.
The Solution
You need to add your development and production domains to your Sanity project's CORS origins:
- Go to manage.sanity.io
- Select your project
- Navigate to Settings → API → CORS Origins
- Click Add CORS origin
- Add your domains:
http://localhost:5173(or whatever port your SvelteKit dev server uses)- Your production domain (e.g.,
https://yourdomain.com)
- Check "Allow credentials" if you need authentication
Additional SvelteKit-Specific Tips
Option 1: Force server-side only (Quick fix)
Add this to your page.ts to prevent client-side re-fetching:
export const ssr = true;
export const csr = false;Option 2: Use SvelteKit's server load (Recommended)
Rename page.ts to +page.server.ts. This ensures the load function only runs server-side, bypassing CORS entirely:
// +page.server.ts
import type { PageServerLoad } from './$types';
import sanityClient from '../../lib/sanity';
export const load = (async ({ params }) => {
const data = await sanityClient.fetch(`*[_type=="project"]`);
return {
name: "Rob",
projects: data
};
}) satisfies PageServerLoad;Option 3: Proxy through SvelteKit (Most robust)
Create an API endpoint in SvelteKit to proxy Sanity requests, keeping all external API calls server-side. This is especially useful for authenticated requests.
Verify Your Client Configuration
Make sure your Sanity client is properly configured with all required fields:
// lib/sanity.ts
import { createClient } from '@sanity/client';
export default createClient({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2024-01-01',
useCdn: true, // `false` if you need fresh data
});The server-side load approach (+page.server.ts) is generally the best practice for SvelteKit + Sanity since it keeps your data fetching server-side, improves performance, and avoids CORS issues entirely.
Show original thread18 replies
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.