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
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
<!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>
<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
-
Define interface and default state for an object
-
Create store with 'st' prefix
-
Import stores in svelte pages
object pattern
Here is a extrapolation from unwritten svelte stores guide adapted to TypeScript.
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()
<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
import sveltePreprocess from 'svelte-preprocess'
export default {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: sveltePreprocess()
}