sveltejs/svelte

Programatically set a `<svelte:boundary>` as pending

Opened this issue · 2 comments

Describe the problem

It would be nice if the <svelte:boundary> had a property (maybe bindable) that could be used to set it as pending when no async work is being done. I have an auth library that connects to my backend before my site is ready. I want to show a loading state for this, so I use an {#if}{/if} for that. One of the problems is that the loading spinner has jank because it's rendered twice, once for async work and once for auth loading. This is undesirable for me.

Another use case would be to trigger the loading spinner during client navigations.

Describe the proposed solution

<script>
    let isPending = $state(false);
</script>
<svelte:boundary bind:{isPending}>
	<p>{await delayed('hello!')}</p>

	{#snippet pending()}
		<p>loading...</p>
	{/snippet}
</svelte:boundary>

Something like this would be nice to see. The boundary would still be pending when async work is done, but also when isPending is true

Importance

would make my life easier

I've similar use case:

  1. component has state as the top
  2. after pending promise is resolved I would love to update the state

Didn't find a way to do that

Welp, my best workaround is:

<script lang="ts">
  import Tags from '$lib/components/tags.svelte'

  let tagsReceived = $state(false)
</script>

<p>Received tags - {tagsReceived}</p>

<svelte:boundary>
  <Tags bind:tagsReceived />

  {#snippet pending()}...{/snippet}
</svelte:boundary>

and a component with remote function:

<script lang="ts">
  import { getGroupedTags } from '$lib/remote/get-grouped-tags.remote.ts'

  let { tagsReceived = $bindable() }: { tagsReceived: boolean } = $props()

  const tags = await getGroupedTags()

  tagsReceived = true
</script>

<p>tags - {tags.length}</p>

Not sure if it's the recommended way, but hey, it works 🤔