Create an application with Svelte

Totsawin Jangprasert
Nerd For Tech
Published in
6 min readMay 2, 2021

I am using Svelte to build the web application.

Svelte and SvelteKit

What is Svelte?

Svelte is a component framework — like React, Vue, or Angular — but with these differences that make Svelte shine out.

  • Write less code: from an example in the article, to create the component that receives two user inputs and prints the sum of these inputs, React and Vue takes 442 and 263 characters respectively while it can be done in 145 characters in Svelte.
  • No virtual Dom: Svelte takes different approach on updating the user interface. Instead of using the famous technique like virtual DOM diffing, Svelte writes code that surgically updates the DOM directly when the state of the app changes. This can eliminate the task of comparing the new virtual DOM with the previous snapshot, done in the virtual DOM diffing technique.
  • Truly reactive: From the below example, Svelte uses label, $, to declare that the values of two variables, characters and words, depend on the value of variable, text, and they will be automatically re-computed when the value of text variable changes.

Angular enables reactive programming due to RxJS and observables, and Vue.js allows to reactively recompute values with computed properties. As for Svelte, it makes use of a lesser known JavaScript feature, labels , to allow reactive declarations and reactive statements. This means that you can have certain values be recomputed automatically when certain other values change. This is really powerful, and as you’ll see, Svelte makes it easy as pie. (Alligator.io, 2019)

<script>
let text = '';

$: characters = text.length;
$: words = text.split(' ').length;
</script>

<style>
textarea {
width: 100%;
background: aliceblue;
font-size: 2rem;
}
</style>

<textarea bind:value={text} rows="10" />

<p>Character Count: {characters}</p>
<p>Word Count: {words}</p>

I really recommend you to watch Rethinking reactivity by Rich Harris, the creator of Svelte, I like it until I would say that if you can pick one video to watch, I would recommend you to watch this one. It makes you rethink about the current state of frontend frameworks and, at the end, understand the drives behind Svelte.

‘Rethinking Reactivity’ from You Gotta Love Frontend by Rich Harris

What is SvelteKit and Why not use it?

SvelteKit is a framework for building Svelte web application. SvelteKit bring lots of features for building modern web application — code-splitting, offline support, server-rendered views with client-side hydration.

As my goal is to build one simple page Svelte application, for simplicity I will not use SvelteKit. When I start adding new feature to this application, I might consider migrating to it. As a result, I will follow the official guide, The easiest way to get started with Svelte, to develop Svelte web application.

Implementation

  1. pull the following repository, sveltejs/template — project template created by Svelte team, out of git and put it in local hard drive in a folder called, abolish112 — which I will use it as the project name.

note: Degit is like cloning the repository but without git history.

npx degit sveltejs/template abolish112 

2. go inside the project folder

cd abolish112

3. install dependencies

npm install

4. start the application in local

npm run dev

You will see the application up and running in local.

the Svelte application is up and running in local on http://localhost:5000/

5. Look inside /src folder, you’d see there are only 2 files i.e. main.js and App.svelte.

First, look at main.js

  • target is an HTMLElement to render to,
  • props are properties being passed to the component
import App from './App.svelte';const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;

You can try changing the name property to something else and notice what is changing in the UI after saving.

Secondly, look at App.svelte. You would notice that this consist of 3 main blocks

  • <script> block contains JavaScript that runs when a component instance is created. Variables declared (or imported) at the top level are 'visible' from the component's markup.
  • <main> or other HTML tag
  • <style> block contains CSS which will be scoped to this component.
<script>
export let name;
</script>
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.
</p>
</main>
<style>
main {
text-align: center;
padding: 1em;
max-width: 240px;
margin: 0 auto;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
@media (min-width: 640px) {
main {
max-width: none;
}
}
</style>

6. In my example, I will get rid of the props as it is not necessary in my application to pass the properties from the parent down to the component. The end result is main.js and App.svelte would be like:

main.js: remove props

import App from './App.svelte';const app = new App({
target: document.body
});
export default app;

App.svelte: remove namevariable from <script>and <main>

<script>

</script>
<main>
<h1>Hello!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.
</p>
</main>
<style>...

The current UI would be:

7. The actual implementation would start from here. Per below, I’d like to display an image of Thai pro-democracy activist who has been already detained for nearly 3 months. This composes of 3 sections i.e. name, caption and image.

7.1 Start from downloading the image from the google drive: https://drive.google.com/drive/mobile/folders/15SmPO5AQKhHzylszDeWDFH0JJ7z1O87f?usp=sharing

7.2 Create the /assets folder inside /public folder and place the image inside this folder.

project folder structure

7.3 Go back to App.svelte. Start with <script> block, I create 3 constant variables and 1 function — they will be bound to the markup in next step.

<script>
const todayDate = new Date();
const DAYS_IN_MS = 24 * 60 * 60 * 1000;
const person = {
name: `Parit 'Penguin' Chiwarak`,
detainedDate: new Date(2021, 1, 9)
}
function getNumberOfDaysUnderDetained(detainedDate) {
return Math.floor((todayDate - detainedDate) / DAYS_IN_MS);
}
</script>
<main>...<style>...

7.4 In <main> block, personobject and getNumberOfDaysUnderDetainedfunction are bound inside the markup with interpolation syntax {}.

<script>...<main>
<div class="individual">
<div class="individual__name">{ person.name }</div>
<div class="individual__caption">
<span>
{getNumberOfDaysUnderDetained(person.detainedDate)}Days Held Under Trial
</span>
</div>
<div class="individual__image">
<img src="./assets/penguin.jpg" alt="{person.name}"/>
</div>
</div>
</main>
<style>...

7.5 Lastly, I decorate as follows. If you are interested in CSS Grid, I will have another blog post on this one.

<script>...<main>...<style>
:global(body) {
/* this will apply to <body> */
background-color: black;
margin: 0;
}
main {
text-align: center;
padding: 1em;
max-width: 640px;
margin: 0 auto;
}
.individual {
position: relative;
width: 100%;
margin: 0 auto;
background-color: #4a4a4a;
color: #fff;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
display: grid;
font-family: "helvetica", "arial", sans-serif;
grid-template-rows: 10% 5% auto;
}
.individual__name {
align-items: center;
display: grid;
font-size: 1.5em;
font-weight: bold;
padding-left: 1rem;
border-bottom: 1px solid;
}
.individual__caption {
color: #f9f2e2;
align-items: center;
display: grid;
font-size: 1em;
padding-left: 1rem;
border-bottom: 1px solid;
}
.individual__image {
position: relative;
background-color: #98d6f7;
overflow: hidden;
}
img {
width: 100%;
height: 100%;
}
</style>

As this blog post seems too long, I will further demonstrate how to use {#if...}expression and {#each...}expression in order to make a loop on the array to create the image gallery and, with conditional statement, display the overlay stamp accordingly in the next blog post.

Footnote

*112 in the project name* refers to Section 112 of Thai Criminal Code currently reads as follows: “Whoever defames, insults or threatens the King, the Queen, the Heir-apparent or the Regent, shall be punished with imprisonment of three to fifteen years.”

Reference

  1. Svelte
  2. Svelte Kit
  3. An intro to Svelte with John Papa

--

--

Totsawin Jangprasert
Nerd For Tech

Lead Developer at ExxonMobil. Passion in frontend development. Love minimal design, travelling, reading, watching and Wes Anderson. Support Thai democracy |||