Feedback form with Svelte
Tags: svelte, sveltejs, howto, modernjavascript
Published: 2019-10-19 18:56:29

---
title: Feedback form with Svelte
published: true
description: bootstrap Svelte project and create interactive form functionality
tags: svelte, sveltejs, howto, modern javascript
cover_image: https://thepracticaldev.s3.amazonaws.com/i/o5fict5mlmtx34zufxy0.png
---

In this article I will show you how you can setup a Svelte project, add basic frontend form functionality with Svelte and then build the project.

If we are considering to building practical piece of UI - I'd propose choose a feedback form for example. Internet already has millions of todo-app tutorials. Our form will have multiple fields, basic validation and option to send data to a backend API using fetch API.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/beaod06dpahklyjdbkzn.png)

<strong>Why Svelte</strong>
About 3 years ago Svelte library was created by <a href="https://twitter.com/Rich_Harris">Rich Harris</a>. One of the biggest differences of that new framework was that it’s not relying on Virtual DOM like popular modern solutions, such as ReactJS or VueJS.
According to its author Svelte however is more than just a framework, it's an another approach towards easier building reactive UIs, language if you will - <a href="https://gist.github.com/Rich-Harris/0f910048478c2a6505d1c32185b61934">read more on this in this gist</a>.

<h2>Bootstrap Svelte project</h2>

We can create a new project using following command:
<code>
npx degit sveltejs/template <FOLDER_NAME_HERE>
</code>
What we do here is call a <code>degit</code> tool to generate the new project using a template config named <code>sveltejs/template</code> in the folder that you provide as a last parameter.
Since we use <code>npx</code> <a href="https://www.npmjs.com/package/npx">npx documentation here</a> we are not installing <code>degit</code> into the system, but you can always install it like this
<code>
npm install -g degit
</code>
then scaffolding next Svelte app (in this case it's just cloning the template repo) will be faster, just by calling <code>degit sveltejs/template <FOLDER_NAME_HERE></code>

Ok, so the script was fast to run, let got to the folder and see the structure we have there:
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/stvxup5rjfur3kc74jzj.png)
I will be using Visual studio code for further development. We can see we have a single svelte file created, that contains basic code, we have a config for a bundler (Rollup is default, however, you can also use Parsel and Webpack) that is used <code>rollup.config.js</code> and a <code>package.json</code>. Let's check what commands we have in it:
<code>
  "scripts": {
    "build": "rollup -c",
    "autobuild": "rollup -c -w",
    "dev": "run-p start:dev autobuild",
    "start": "sirv public --single",
    "start:dev": "sirv public --single --dev"
 }
</code>

So to start developing we will need to run <code>dev</code> command. What it will do - it'll run in parallel (thanks to special <code>run-p</code> command) the static assets server - <code>sirv public</code> and a bundler in a watch mode: <code>rollup -c -w</code>. This will provide us with live update of the page any code files changes

So as we start we should see such output in the console:
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/epci0t4gne2auypgidx6.png)
It mean all went well so let's open <code>localhost:5000</code> in the browser and see what we'll get. You'll see a really basic output which only contains one line of text with dynamic variable <code>{name}</code> in it.
{% gist 
https://gist.github.com/shershen08/da510f5048e29eb926b4fbc0927def68 %}

Concerning the other files and app structure the sequence is as follows:
<code>
Other components -> App.svelte -> main.js 
</code>
So app instance initialisation code is in the <code>main.js</code> file and since they're pretty simple it looks like this:
{% gist 
 https://gist.github.com/shershen08/da510f5048e29eb926b4fbc0927def68 %}

During the compilation step it is all consumed by Rollup or other bundler and it wild output it in index.html and <code>/public</code> folder.

<h2>Form logic</h2>
Currently our app.svelte file doesn't contain much. So let's get into it and add some UI markup. You can write with yourself or you can copy it from some <a href="https://bootsnipp.com/similar/vO0d">Bootstrap form samples page</a>.

So here's how your form may look like. No dynamic elements, just HTML markup.
{% gist  
https://gist.github.com/shershen08/8d1c4cf39e63f217a22c35bd3b077efb %}

Markup in Svelte is pretty easy, all the CSS, JS and HTML can be combined in one file (same you can do in <a href="https://vuejs.org/v2/guide/single-file-components.html">Vue</a>). All the JS code is between the script-tags, and the component styles are... you guessed it, is in style tags. Good to know that CSS written in svelte files is scoped.

Again, if using Visual Studio code for editing I would recommend to install <a href="https://github.com/UnwrittenFun/svelte-vscode">extension svelte-vscode</a> that will manage code highlighting and many more for you.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ilu9kzb9o7nphvw9w2ny.png)

<strong>State</strong>
What is the most important to do right in modern frontend apps - of course it's the State. It's easy to start building something small ignoring the right approach to managing the state and then find yourself in situation that you need to refactor all the code you recently wrote.  Everything depends on everything, unexpected side effects start to appear.
So let's create a simple state object:
{% gist https://gist.github.com/shershen08/1abbfe797d28e1a18d6584720b70ed3d %}
It is quite simple but later you may want to put it into Redux or persist in localStorage or what will you.

<strong>Form</strong>
Let's add a markup with using several Svelte features:
{% gist https://gist.github.com/shershen08/35dea09c72bce6700317f456448a5030 %}

Let's see what are those:
 - <code>{#if STATE.send.success}</code> - way to show/hide certain blocks of markup based on the model value; <code>{#}...{/}</code> is a common way to structure templates in Svelte;
 - <code>{@debug STATE} </code> - offers an alternative to console.log(...). It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open;
 - <code>on:click={validateAndSend}</code> - Svelte way to bind event handlers on DOM element; in this case it's a button;

<h2>Sending data</h2>
In the JS logic the <code>validateAndSend</code> function will do the following:
 - retrieving of data using FormData 
 - validation 
 - if all is successful it will send it to backend
 - update the UI with success/failure

Here's how its looks like:
{% gist 
https://gist.github.com/shershen08/9e776fdf20037eaa6a5c05c9ece98e90 %}

All the functionality that can be separated such as validation and sending data over the network I've extracted to separate <code>/service.js</code> file. 

<strong>Building the app</strong>

Now if you see that the functionality that we expected is working as it should let's try to run the production build with: <code>npm run build</code>
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/vndltsxknr0sct151sqi.png)

Look at the time it took to build the whole app. Of course our app is really tiny but still your can see that the overhead for the framework part of the build is negligible in case of Svelte.

Here's how the generated html-page looks like,
{% gist 
https://gist.github.com/shershen08/64f4bebed730bc00abd6bbce0a8221f9 %}
It contains one link to the JS bundle and separate links to stylesheets that you may want to use. It comes really handy when you have part of your styles refused from readymade style sheet - like using Bootstrap or material design CSS.

Here's a basic feedback form app that you can build with Svelte. 
Hope some of the framework features while reading this article, along with the approaches towards managing modules and state in frontend apps.

All the code is also stored in the separate <a href="https://github.com/shershen08/feedbackform-svelte">shershen08/feedbackform-svelte repo </a>. Please have look at it if you'll have any questions.

I'll be happy to answer your questions in the comments or in Twitter: <a href="https://twitter.com/legkoletat">@legkoletat</a>.