A collection of useful features encountered when working with Svelte and Svelte-Kit
We often want to load our page before concentrating on resource-heavy items such as videos. Here we use a promise to check the page is ready, before loading those components.
let domReady = (function ()
return new Promise( function(resolve)
document.addEventListener('readystatechange', function()
if(document.readyState != 'loading' && document.readyState
!='interactive') resolve();
)))()
Now we can use the asynchronous await conditional when adding components:
#await domReady
<MyComponent />
/await
Often we may want to load a library from a CDN for testing or to reduce the overall svelte-kit bundle size or compile time. Here we make use of the svelte:head
option to do so.
<svelte:head>
<script defer src='http://...loading1.js'></script>
<script defer src='http://...loading2.js'></script>
</svelte:head>
Of course, if we so should want, we could also use the dynamic import(...)
or even vanilla JavaScript methods:
function loadScript(src) let script = document.createElement('script')
script.src = src;
script.async = false;
document.body.append(script);loadScript("loading1.js");
loadScript("loading2.js");
Sometimes we may want to read ‘events’ that happen to the window. An easy way to do this is to bind them to svelte:window
:
<svelte:window on:keydown=keyed/>
And treat them as normal with the callback function.
function keyed(event)
key = event.key;
keyCode = event.keyCode; if (key === ' ' ) alert('you pressed space')
To update a variable across multiple components we can make use of svelte stores
. To do this we define a shared file (eg, sharedvalues.js
) and our variables:
import writable from 'svelte/store';export const contact = writable(name:'Dan', age:undefined);
Then within each of our svelte scripts, we can import the variables and update them.
import contact from './sharedvalues.js';console.log('hello', $contact.name)
We can also update these with:
$contact = name:’Dan’, 101
or contact.set(name:’Dan’, age:101)
In the case where we wish to run an update each time a store value is changed, we just have to subscribe a callback function to it. The location of the change is irrelevant just as long as both routes / components are sharing the same svelte store.
function onChange()
console.log('hello', $contact.name)
contact.subscribe(onChange)
Another way to communicate between svelt components comes in the form of the event dispatcher. Here we create a custom event name and send an object with our information.
import createEventDispatcher from 'svelte'; const dispatch = createEventDispatcher();dispatch('myEventName', name:'Dan');
We can then ‘bind’ this to a component in the form:
<script>function onChange(event)
console.log('hello', event.detail.name)
</script>
<Component ... on:myEventName=onChange />
There exists yet another way to read information, without passing it around, and this is using the svelte context. It is useful in cases where you wish to define a set of configuration parameters on the app level of the script, which can then be accessed by each child component.
//App.svelte import setContext from 'svelte'; setContext('user', name:Dan );
We can read this from the child component with the following:
import getContext from 'svelte'; const user = getContext('user');
In some situations, we want to bind events to changes to the window object. Here we use the svelte:window
object and bind a variable to its width.
<script>
let w
</script><svelte:window bind:innerWidth=w/><OneThirdComponent style="width:w/3px" />
In a similar manner, we may bind our scroll position to our script and trigger updates to our website:
<svelte:window bind:scrollY=y/>#if y > 100#each layers as layer
<parallaxComponent
style="transform: translate(0,-y * layer / (layers.length - 1)px)" >
/each/if
A great feature in svelte is that styles are scoped, however, this can cause problems when you wish to change an externally imported component.
The solution is to define a global style, which affects every component matched by your query parameters.
<style>
:global(.myComponentClass)
display:flex
</style>
We are also able to render HTML strings directly, without the need to append them to existing DOM elements.
<script>
var htmlString = `<img src="$img.src"/>`
</script>@html htmlstring
When creating a component, we can nest other components / HTML code within them. This is done using slots.
//Component.svelte<div> <slot>Default content</slot> </div>
And then anything that is placed between the open and closing tags of components replaces the ‘default content’ slot.
<Component>
<p>My super cool changed content</p>
</Component>
Slots can also be named if you require multiple substitutions.
We can also bind a component without the need for setting ids or queriable features. This is done by using its self (or this) reference, as shown below:
<script>
let component;
</script><svelte:component this=component />
The perks of this method mean we can dynamically change the component we are looking at by using, say, a selection tool.
Finally, we can easily tween values and add animation to our website using the motion and easing libraries in svelte.
In UI development adding a class based on a conditional (eg class="status === 'loaded' ? 'loadedclass':''"
that Svlete adds its own class directive for ease of reading. This can be used as:
<Component class:loadedclass=status === loaded />
A collection of some useful svelte tricks I have found. Although this list is likely to be updated as I go on, feel free to add anything you find useful to the comments.