These posts are aggregated from Svelte GitHub Repository.
I'm using Svelte 5 within an Astro project.
I pass a locale prop from Astro to a Svelte component, and this locale never changes during the component's lifecycle.
<script>
import { getRelativeLocaleUrl } from 'astro:i18n';
import { getTranslator } from '$lib/i18n';
let { locale } = $props();
// Warning: state_referenced_locally
// But strictly necessary for initialization
const t = getTranslator(locale);
const homeUrl = getRelativeLocaleUrl(locale, '/');
</script>
<a href={homeUrl}>{t('home')}</a>
Should I wrap these in $derived() even though I know they will never re-calculate?
This is perhaps a silly question, but it's something I ran into at work.
We have a couple of components which are using JS libraries to defer the displaying of some content within our written articles and blogs.
There is also a unit test, broken down to it's very basic pieces, you get something that looks like this:
// special.svelte
<script>
// Other code here
</script>
<svelte:head>
<script>
// some required args for the library
window.SOME_LIBRARY = { disable_autoload: true };
</script>
<!-- not the actual library, but to show the point that something has to load here -->
<script src="https://code.jquery.com/jquery-3.7.1.slim.min.js" defer></script>
</svelte:head>
<!-- other HTML here -->
In practice, this works fine when testing on a browser, but someone well before I got there created a test that looks something like this
import { render } from '@testing-library/svelte';
import { describe, expect, it } from 'vitest';
import Special from './special.svelte';
describe('Special', () => {
it('Does its special thing', async () => {
render(Special);
expect((window as any).SOME_LIBRARY).toBeDefined();
expect(
document.head.querySelector(
'script[src="https://code.jquery.com/jquery-3.7.1.slim.min.js"]',
),
).toBeInTheDocument();
});
});
Which fails, and writing the entire DOM to the console shows me
<html>
<head>
</head>
<body>
<div>
<div>
Loading...
</div>
</div>
</body>
</html>
It seems that in svelte 5 (I haven't been able to test on svelte 4) the <svelte:head> contents are not being applied in test environments.
Anyone got any ideas how I can fix this?
Vue has props in transtition mode - https://vuejs.org/guide/built-ins/transition#transition-modes appear - https://vuejs.org/guide/built-ins/transition#transition-on-appear are there analogs for svele? As I see, svelte always use 'default', so removed and added DOM elements both exists while playing transition and always plays on mount
[!NOTE] this post is a collection of ideas and goals and things will be refined based on the discussion that follows, nothing is set in stone yet.
As Rich mentioned briefly during his svelte summit talk we are working on a toolbar to improve DX and allow better insights into svelte applications.
regardless of how you use svelte, adding the toolbar should give you access to the tools in our ecosystem
svelte/toolbar. svelte/toolbar or other packages within the org (eg bundler plugins)While we are going to provide first party tools, we also want to provide an api to add third party tools and allow customization
The toolbar itself and each tool has a configuration that can be modified by invoking a function provided on svelte/toolbar
The configuration is going to be stored locally so you can tailor it to your needs and it stays that way. Possible storage locations would be localstorage, indexeddb or .env.local files.
Most tools are going to be available during dev, but some can also be used in a production build.
to be ported from vite-plugin-svelte , its functionality is going to remain the same, but instead of hardcoding how file editors are opened by a call to a vite middleware, it is going to leverage the devserver integration
visual editor for the toolbar config, with options to persist
$inspect is nice and surgical, but it would be even nicer if there was a way to visualize the reactivity graph and more easily follow dependencies through your app. Solid already has a tool for this and so should we
params, matchers, layout groups, the file system tree can become a bit messy. A dedicated ui with links to open the relevant files can help understand and work with your application structure.
The original svelte devtools browser extension had this view, and we can bring it back.
please share ideas for tools you'd like to have/build and any apis they might need. now is the time to shape the foundation
The toolbar itself is going to provide basic common features to the tools and renders them with provided name&icon. Of course it is going to be a svelte component and to avoid colliding with your application it will be mounted on document.documentElement outside of body by default, which should avoid collisions with your app in most cases.
A tool needs to be registered with the toolbar and receives api & configuration. Optionally it can provide its own svelte component for ui. If the toolbar is going to add this component or the tools is responsible for mounting it is still up for discussion.
Ideally, bundler plugins are going to inject the toolbar to avoid the need for putting code into your app yourself (like svelte-inspector is added today) and the tools just show up as configured. But manually putting them in your root layout can work as well. The hardest one is adding them for production, this might require a web extension and building with a special flag so it can aquire a reference to the toolbar api.
If you want to build a tool, what api do you prefer. Should a tool always be a svelte component or should it be more similar to a vite plugin with an initializer function and hooks?
Do you think tools should be aware of each other and able to collaborate?
What are the most important tools you want to use?
Would you prefer a web extension with ui separately in the devtools tab or is rendering in the apps window ok?
Heyy, made a boilerplate template to kickstart web app development with some prebuilt tailwind components and utilities:
Form validation, view-transitions, staggered animations, prebuilt auth, docs page and many more... check the repo out :D
https://github.com/magooney-loon/svelte-gui
Web demo: https://svelte-gui.vercel.app/
so, i am building a file tree component in svelte which takes an array of objects whith this data structure
export interface FileNode {
name: string;
path: string;
isDirectory: boolean;
children: FileNode[];
}
i built a fully working minimal file tree compoenent with recursive component this (simplified)
<script lang="ts">
// imports itself
import ItemsRenderer from './items_renderer.svelte';
import type { FileNode } from '@/types';
let { file_tree }: { file_tree: FileNode[] } = $props();
</script>
{#if file_tree.length}
<ul>
{#each file_tree as node (node.path)}
<li>
{#if node.isDirectory}
<details>
<summary>
{node.name}
</summary>
<ItemsRenderer file_tree={node.children} />
</details>
{:else}
<div>
{node.name}
</div>
{/if}
</li>
{/each}
</ul>
{/if}
and also with snippits
<script lang="ts">
import type { FileNode } from '@/types';
let { file_tree }: { file_tree: FileNode[] } = $props();
</script>
{#snippet folder_node(nodes: FileNode[])}
<ul>
{#each nodes as node (node.path)}
<li>
{#if node.isDirectory}
<details>
<summary>
{node.name}
</summary>
{@render folder_node(node.children)}
</details>
{:else}
<div>
{node.name}
</div>
{/if}
</li>
{/each}
</ul>
{/snippet}
{#if file_tree.length}
<div class="overflow-y-auto">
{@render folder_node(file_tree)}
</div>
{/if}
now, some things that i didn't include in the code is that,
i wonder which one is more performant?
I am proposing a new primitive (or an enhancement to the upcoming resource API) that enables on-demand, async, memoized, and reactive client-side data fetching.
The goal is to bring the developer experience of SvelteKit’s remote functions (specifically the caching/sharing mechanism) to client-side logic, allowing shared state across components without the limitations of setContext or the complexity of manual cache invalidation.
The usage would look similar to a query remote function but designed for client-side logic (e.g., inside .svelte.js files).
Option A: String Key
import { online } from 'svelte/reactivity/window';
import { memoize } from 'svelte/reactivity'; // Hypothetical import
export const getTodos = (id) => {
return memoize(`/todos/${id}`, async () => {
// Track svelte signals:
if (!online.current) return null;
// Track signals after awaits (e.g. react to remote function refreshes)
const user = $derived(await getUser());
if (!user) return null;
const todos = fetch(`/api/todos/${id}?user=${user.id}`).then((res) => res.json());
// Since they have their own lifecycle, maybe even have an on/off notifier:
$effect(() => {
// e.g. start websocket connection
return () => {
// e.g. cleanup websocket connection
}
});
return todos;
});
}
Option B: Schema/Auto-key (Remote function style)
export const getTodos = memoized(z.string(), async (id) => {
// ...
})
Currently, sharing async state in and outside the component tree is friction-heavy. While setContext / getContext is the standard solution for SSR-safe shared state, it imposes strict limitations in an async environment:
await expression.setContext('key', { get value() { return signal }})).This proposal asks for a primitive that allows data to be defined globally (or in shared modules) and consumed locally, with the framework handling the lifecycle and cache sharing.
I have attempted to implement this pattern in userland, but I have hit specific roadblocks regarding how Svelte 5 handles reactivity across async boundaries.
.svelte.js filesIn Svelte components, $derived(await ...) magically handles signal tracking across await boundaries. However, replicating this inside standard .svelte.js functions is inconsistent.
Although using $derived inside a function technically compiles, the behavior is flaky. Reactivity often fails to track signals correctly if the execution involves complex async flows, or it requires multiple signal changes to "wake up" the tracking.
See reproduction in Playground
$effect.root does not support asyncTo memoize a resource that might be called outside a render effect (e.g., in an event handler), we need to create a root scope using $effect.root. However, $effect.root cannot contain async execution.
I am aware of the upcoming resource primitive in #16960. While exciting, the current design seems to rely exclusively on manual invalidation (.refresh()).
If I have a resource that depends on other resources, I have to manually cascade .refresh() calls. Ideally, the resource should track signals (including other resources) used in its "run" function and automatically re-run when dependencies change, keeping the value up to date without manual intervention.
Hi, I have observed a behavior which I cannot really get my head around and thought I'd ask you guys what the issue might be:
// I do some data fetching here. The result is the conferenceData observable which
// allows subscribing to return values via svelte store syntax
// using the new async svelte, I use await which will guarantee the observable to have a value present
const conferenceData = await client.query.conferenceUsers({
...
});
when I now inspect the subscribed value $inspect($conferenceData) I see undefined and then immediately the actual value when I look into my browser console. Thinking this might be because the initial value might somehow not be set correctly, I wrapped this into a readable which resolves the problem:
const conferenceDataStore = readable(conferenceData, (set) => {
set(conferenceData as any);
const sub = (conferenceData as any)?.subscribe?.((v: any) => set(v));
return () => sub?.unsubscribe?.() ?? sub?.();
});
$inspect($conferenceDataStore)
This never shows undefined.
That's nice. I want to move this to my library so the above call will do this automatically. So I imported svelte/store and did exactly what I did above but in my data fetching library. And the undefined returned. So somehow it makes a difference if the store is created inside my component?!
Anyone have any idea why this happens? I know async is still in beta and I'm not sure if this is an issue on my part or actually needs to be addressed. Thanks for your time!
I'm just picking up Svelte with Carbon Components. I'm trying to do something like the following with Theme.
<Theme
bind:theme
render="toggle"
persist
toggle={{
themes: ["g10", "g90"],
labelA: "Light",
labelB: "Dark",
hideLabel: false,
}}
/>
But instead of "Light" and "Dark" for labels I'd like to use Sun and Moon from carbon-icons-svelte for labelA and labelB. I'm wondering if it's just not possible, because of how the Theme component has been written; the labels being strings, and the icons being <svg>...</svg> nodes?
Have I understood that correctly, or am I missing something?