Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
February 22, 2022 08:11 pm GMT

Build a realtime websocket UI using SvelteKit

We used SvelteKit to make https://typedwebhook.tools - which allows you to test HTTP requests and automatically generates typescript types for the body. Inspired by that, let's run through how to make a realtime websocket UI using SvelteKit.

If you want a sneak preview, the code for typed webhooks is open source: https://github.com/inngest/typedwebhook.tools

Why SvelteKit?

  • Using Vite, it builds fast in dev. And it has HMR with state persistence out of the box. Somehow this is consistently broken in every react app, no matter what kit you use :D
  • It has SSR out of the box. Its built for progressive enhancement, and configuring pre-rendering is the easiest Ive seen
  • State management is easy. Its easy to work with stores. You can (broadly speaking) use the stores from anywhere: no top-level context necessary (ahem, hello websockets!)
  • SvelteKit comes with a standard way of doing things (CSS, JS, forms, state, routing), so its easy to work with and its easy to share amongst devs. Its easy to get set up and running with your entire framework think a mixture of NextJS and create-react-app for Svelte.

Plus, it's amazingly developer friendly

Getting started

Make sure that you have Node & NPM installed, then run:

npm init svelte@next

It'll run you through a guide to set up your base project. Here's how we answered those questions:

 Where should we create your project?  (leave blank to use current directory)  realtime-demo Which Svelte app template?  Skeleton project Use TypeScript?  Yes Add ESLint for code linting?  Yes Add Prettier for code formatting?  Yes

Let's go to that directory and run the dev server:

cd ./realtime-demo && yarn dev

If you go to localhost:3000 you should see Svelte up and running!

The current code lives in ./src. The routes folder (./src/routes) acts as a router: ./src/routes/index.svelte is the index page rendered by default, and ./src/routes/about.svelte is rendered when you navigate to /about.

You might be asking yourself "where do shared components go?". They go in ./src/lib which isn't made by default.

Let's jump to real-time state - the meat of what we're building.

Real-time state

State is saved in stores. A store ihjkjs similar to react's useState value, but way more powerful. We're going to be creating a store that records websocket responses.

Let's make a file for our store in the shared directory: ./src/lib/state.ts.

Inside it, we're going to use Svelte's writeable stores:

// Import the function which initializes a new mutable store.import { writable } from 'svelte/store';type Item = {  id: string;  content: string;};// Our store will record an object containing an array of// items produced by the websocket.type State = {  items: Array<Item>;  error?: string;};// That's it;  state is now usable!  Components can subscribe// to state changes, and we can mutate the store easily.//// Note that this is a singleton.export const state = writable<State>({  items: []});// We also want to connect to websockets.  Svelte does// server-side rendering _really well_ out of the box, so// we will export a function that can be called by our root// component after mounting to connnectexport const connect = (socketURL: string) => {  const ws = new WebSocket(`wss://${socketURL}`);  if (!ws) {    // Store an error in our state.  The function will be    // called with the current state;  this only adds the    // error.    state.update((s: State) => return {...s, error: "Unable to connect" });    return;  }  ws.addEventListener('open', () => {    // TODO: Set up ping/pong, etc.  });  ws.addEventListener('message', (message: any) => {    const data: Item = JSON.parse(message.data);    // Mutate state by prepending the new data to the array.    state.update((state) => ({ ...state, items: [data].concat(state.items) }));  });  ws.addEventListener('close', (_message: any) => {    // TODO: Handle close  });}

We can now use this in our index page, ./src/routes/index.svelte:

<script context="module" lang="ts">  export const prerender = true;</script><script lang="ts">  import { onMount } from 'svelte';  // $lib auto-resolves to ./src/lib in Svelte.  import { state, connect } from '$lib/state';  onMount(async () => {    connect();  });</script><!--  We haven't defined the ItemList component (which should  go in ./src/lib too), but this shows how you can auto-  subscribe to the store using `$state`.  Every time state  updates, $state.items changes and this will re-render--><ItemList items={$state.items} />

This shows the power of Svelte, SvelteKit's routing, and state management. You can access state from anywhere in your app - no component hierarchy needed - and it's super easy to use within your components.

Svelte is incredibly powerful and developer efficient. Give it at try!


Original Link: https://dev.to/tonyhb/build-a-realtime-websocket-ui-using-sveltekit-4jf3

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To