SSR & Loading States

Goal: Handle loading, data, and error states properly. Use SSR hydration to avoid spinners.

The three states

Every stream store can be in one of three states:

{#if $messages === undefined}
  <p>Loading...</p>
{:else if $messages?.error}
  <p>Error: {$messages.error.message}</p>
{:else}
  {#each $messages as msg (msg.id)}
    <p>{msg.text}</p>
  {/each}
{/if}

Always handle all three.

SSR hydration

Load data server-side to skip the loading state entirely:

// src/routes/chat/+page.server.js
export async function load({ platform }) {
  const { messages } = await import('$live/chat');
  return { messages: await messages.load(platform) };
}
<script>
  import { messages } from '$live/chat';
  let { data } = $props();
  const msgs = messages.hydrate(data.messages);
</script>

{#each $msgs as msg (msg.id)}
  <p>{msg.text}</p>
{/each}

The store starts with SSR data instead of undefined. It still subscribes for live updates - but the user never sees a loading spinner.

Was this page helpful?