SvelteKit `{#each}` loop returns null when accessing array item properties
This looks like a classic issue with how GROQ queries handle arrays and null values in Sanity, rather than a SvelteKit-specific problem. When you can JSON.stringify() an item but can't access its properties, it usually means you're getting null values mixed into your array.
Here are the most likely causes and solutions:
1. Array contains null values from your GROQ query
This is the most common culprit. If your sections array has any null entries (from references that don't resolve, conditional fields, etc.), Svelte will try to iterate over them. The JSON.stringify() works because it handles null gracefully, but item._type fails when item is null.
Fix: Filter out nulls in your GROQ query or in your template:
{#each data.homepage.sections.filter(Boolean) as item}
<section class="promo">
{item._type}
</section>
{/each}Or better yet, fix it in your GROQ query by adding a filter:
*[_id == "homepage"][0] {
sections[defined(_type)] // or sections[!(_type == null)]
}2. Missing projection in your GROQ query
If you're querying references or complex types, make sure you're properly dereferencing them. For example:
// Instead of just:
sections
// Use:
sections[] {
_type,
// other fields you need
}The [] syntax ensures you're properly expanding array items.
3. Reactive data loading timing
Since you mentioned it "worked yesterday," this could be a timing issue where the data isn't fully loaded when the template renders. Add a safety check:
{#each data.homepage.sections ?? [] as item}
{#if item}
<section class="promo">
{item._type}
</section>
{/if}
{/each}4. Check your load function
Make sure your +page.server.js or +page.js is properly awaiting the Sanity query:
export async function load({ fetch }) {
const data = await client.fetch('your query');
return { homepage: data };
}The fact that JSON.stringify(data.homepage.sections[2]._type) works but iterating fails strongly suggests you have null values at different indices in the array. Try logging the full array to see what's actually in there:
<pre>{JSON.stringify(data.homepage.sections, null, 2)}</pre>My bet is you'll see some null entries mixed in with valid objects, and filtering them out (either in GROQ or in your template) will solve your issue. The SvelteKit integration with Sanity works great, but GROQ query structure is key to getting clean data.
Show original thread5 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.