Updates

These posts are aggregated from Svelte GitHub Repository.

  • Svelte Philosophy

    This is an attempt to articulate the Svelte philosophy — our bedrock principles, that guide our design decisions.
  • Make await works in <script> with <svelte:boundary>

    Testing the new await and <svelte:boundary> features, I came to the conclusion that using await within the <script> tag should have the same effect as when used within <svelte:boundary>.

    <script>
        //
    </script>
    <svelte:boundary>
        {@const result = await promise}
        {#snippet pending()
            Pending
        {/snippet}
    </svelte:boundary>
    

    If I run the code above, the pending component is rendered normally.

    <script>
        const result = await promise;
    </script>
    <svelte:boundary>
        {#snippet pending()
            Pending
        {/snippet}
    </svelte:boundary>
    

    If I run the code above, the pending component is not rendered. Why this is a problem: if I need to use the result value inside the <script> tag, initially, I can't in the first example. In the second one, I can manage it, but I lose the "effect" of the pending snippet. One solution would be to use {result = await promise} inside <svelte:boundary>, but that would generate "dirt markup" within the HTML.

  • Svelte Matrix room

    Due to the Discord Moment, now it the right time to join Matrix - open-source Discord alternative with end-to-end encryption support.

    We created #Svelte:matrix.org and welcome anyone to join it. The Svelte contributors are getting high ranks automatically.

    The bridge with Discord is also possible.

  • How to define a default value for properties in svelte 5..

    How do I define a default value for component props? Do I have to mark them as accepting undefined? The following doesn't work and tells me I need to provide the values that have defaults assigned:

    let { id, name, color = "default", isValid = $bindable(true), mask, value = $bindable(), validator, required = false, readonly }: Props = $props();

  • fetch, {#await}, and its result's reactivity.

    A common pattern is to fetch data (usually based on a reactive id), then edit the data fields, and finally save.

    As far as I understand, it's not a best practice to fetch data in $effect and it's better to use {#await} blocks. But the issue is that the result's fields are not reactive...

    What recommendations are there for this use case?

  • Attached Transitions/Animations

    Transitions and animations are great out-of-the-box tools from Svelte, but as Attachments improved greatly on the flexibility of Actions, I think we need a similar update to these directives.

    We could implement some attachment to run a WAAPI animation on a child component/node and spread it down through props with createAttachmentKey(), but one feature is missing: the ability to synchronize the cleanup function with the lifecycle of the component.

    This is a poor, hacky attempt show what I mean:

    <script>
    // imports...
    
    let promise = $state(new Promise<boolean>((resolve) => resolve(true)));
    const input_attributes: HTMLInputAttributes = {
      [createAttachmentKey()]: (node) => {
         // Normal reactivity to state...
         
        return () => {
          node.style.background = 'red';
          setTimeout(() => {
          promise = new Promise(() => false);
          }, 1000);
        };
      }
    };
    </script>
    
    {#await promise}
      Waiting....
    {:then value}
      {#if value}
        <Child {...input_attributes} />
      {/if}
    {:catch error}
      {error}
    {/await}
    

    Does anyone have a better way of doing this? Or do you think it is the purview of the framework to provide an elegant way to synchronize these primitives?

  • Props type inference in Svelte 5: infer most, specify some?

    Hello, I'm doing a sizeable Svelte 4 -> 5 migration, and I've encountered some components which have many props with default values.

    In Svelte 4, Svelte/TS could infer the types of the props using their default values. For those props that did not have a default value, it was possible to explicitly specify their type while keeping inference for the rest.

    I haven't found a way to do this in Svelte 5 without explicitly specifying the type for each property. Am I missing something?

    Here's an excerpt from the codebase with a few default values:

    Svelte 4:

      export let accept: string | string[]; // <-- notice this is the only prop with a specific type definition
      export let disabled = false;
      export let maxSize = Infinity;
      export let minSize = 0;
      export let multiple = true;
    

    In Svelte 5, two changes are needed, as far as I could find:

    1. Every property has to be explicitly specified in a separate type definition.
    2. Every property which has a default ("fallback") now needs to be made optional, otherwise the component user still has to provide it.
      type Props = {
        accept: string | string[];
        disabled: boolean;
        maxSize?: number;
        minSize?: number;
        multiple?: boolean;
      };
    
      let {
        accept,
        disabled = false,
        maxSize = Infinity,
        minSize = 0,
        multiple = true,
      }: Props = $props();
    

    What doesn't work:

      // Svelte 5: if we try to specify a type only for `accept`, we get errors like:
      //  > Property '.......' does not exist on type '$$ComponentProps'.
      let {
      .... props with default values....
      }: { accept: string | string[] } = $props();
    

    Is the conclusion that Svelte 5 is just unavoidably more verbose in this situation?

  • How to build a JWT-based session system when you can’t set cookies in a query function?

    I have a JWT session system using long-lived and short-lived tokens. I’m making a request to a query function, but the short-lived token has expired. My logic is to use the long-lived token to verify the user in the DB, return the requested data, and ideally send back a new short-lived token as a cookie to save a DB trip on the next few requests.

    However, I’m getting an error: Error: Cannot set cookies in query or prerender functions. Since this is my first time implementing JWT sessions from scratch, am I doing something wrong, or is there a workaround? Also, why does this limitation exist? It feels arbitrary, but I assume it’s for cacheability, though I wouldn't want these requests cached anyway, as they’d return stale data.

  • Passing Data Back to Parent with Scoped Slots

    Is it possible to pass data into a component and have the component expose that data back for custom rendering?

    // ComponentA.svelte
    
    <script>
        let { rows } = $props();
    </script>
    
    {#each rows as row (row.id)}
        {#if row.dataType === 'custom'}
            // How to render this?
        {/if}
    {/each}
    
    // Usage
    <script>
        const rows = [
            {
                id: 1,
                dataType: 'one',
            },
            {
                id: 2,
                dataType: 'two',
            },
            {
                id: 3,
                dataType: 'custom',
            },
        ];
    </script>
    
    <ComponentA {rows}>
        {#Custom (data)}
            // How to pass this and use the data?
        {/Custom}
    </ComponentA>
    
  • Possible bug for render

    Take a look at the below minimal example:

    <script lang="ts">
         interface Props {
            start?: Snippet;
            end?: Snippet;
        }
    
        let {start, end}: Props = $props();
    </script>
    
    <div>
        {@render start?.()}
        <h1>Hello</h1>
        {@render end?.()}
    </div>
    

    Now there is an error: Svelte: Cannot find name 'end'. Is this is a bug or am I missing anything?

    Thank you in advance.

Loading Svelte Themes