Skip to content

svelte 4

intro

We will focus here on Svelte usage for static websites (JAMstack arch), as opposed to Server-Side Rendering (SSR, check Svelte docs)
SvelteKit integrates a built-in router, but since mid-2022, its routing is just... weird (personal viewpoint).
So target setup is SvelteJS + Vite (bundler) + Page.js (router)

install

install Vite in a nodeenv with Svelte option.

config

Vite

Vite configuration for SvelteJS.

/svelte.config.js

/svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

export default {
  // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
  // for more information about preprocessors
  preprocess: vitePreprocess(),
}

usage

/src/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <!-- UIkit CSS -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.14.3/dist/css/uikit.min.css" />
        <!-- UIkit JS -->
        <script src="https://cdn.jsdelivr.net/npm/uikit@3.14.3/dist/js/uikit.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/uikit@3.14.3/dist/js/uikit-icons.min.js"></script>


        <link rel="stylesheet" href="./style.css" />

    <title>FlowTab</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>
/App.svelte
<svelte:component this={page}></svelte:component>


<style>
  .logo {
    height: 6em;
    padding: 1.5em;
    will-change: filter;
  }
  .logo:hover {
    filter: drop-shadow(0 0 2em #646cffaa);
  }
  .logo.svelte:hover {
    filter: drop-shadow(0 0 2em #ff3e00aa);
  }
  .read-the-docs {
    color: #888;
  }
</style>


<script lang="ts">
  import index from './routes/index.svelte'
  import board from './routes/board.svelte'

  import router from 'page'

  let page

  router('/', () => page = index)
  router('/board', () => page = board)

  router.start()

</script>

stores

Warning

Stores must not be seen as session storage tool.
Any page reload will clear stores.

classic pattern
  1. Define interface and default state for an object

  2. Create store with 'st' prefix

  3. Import stores in svelte pages

object pattern

Here is a extrapolation from unwritten svelte stores guide adapted to TypeScript.

Main.ts
import { Wallet } from 'Wallet'

class mainState {
    loaded: boolean = false
    wallet: Wallet = new Wallet()
}

const _mainState = writable<mainState>(new mainState)

export class Main extends mainState {

    subscribe = _mainState.subscribe
    set = _mainState.set
    update = _mainState.update

    async load_wallet(): Promise<void> {
        await this.wallet.load()
        _mainState.update((self: mainState) => {
            self.wallet = this.wallet
            return self
        })
    }

    init() {

    }
}

export let main = new Main()

App.svelte
<div>{$main.wallet.name}</div>

<script lang="ts">
main.load_wallet()
</script>

extensions

svelte-select

npm install svelte-select@4.4.7 (last major is 5, breaking changes: isMulti, more verbose for isCreatable...)

tips

common a11y errors

<!-- svelte-ignore a11y-click-events-have-key-events -->
a11y shows error when biding on:click to <span>

REST routes

deprecated

svelte config
/svelte.config.js
import sveltePreprocess from 'svelte-preprocess'

export default {
  // Consult https://github.com/sveltejs/svelte-preprocess
  // for more information about preprocessors
  preprocess: sveltePreprocess()
}