loading...
Cover image for Feedback form with Svelte

Feedback form with Svelte

legkoletat profile image Mikhail Kuznetcov ・5 min read

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

Why Svelte
About 3 years ago Svelte library was created by Rich Harris. 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 - read more on this in this gist.

Bootstrap Svelte project

We can create a new project using following command:

npx degit sveltejs/template

What we do here is call a degit tool to generate the new project using a template config named sveltejs/template in the folder that you provide as a last parameter.
Since we use npx npx documentation here we are not installing degit into the system, but you can always install it like this

npm install -g degit

then scaffolding next Svelte app (in this case it's just cloning the template repo) will be faster, just by calling degit sveltejs/template

Ok, so the script was fast to run, let got to the folder and see the structure we have there:
Alt Text
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 rollup.config.js and a package.json. Let's check what commands we have in it:

"scripts": {
"build": "rollup -c",
"autobuild": "rollup -c -w",
"dev": "run-p start:dev autobuild",
"start": "sirv public --single",
"start:dev": "sirv public --single --dev"
}

So to start developing we will need to run dev command. What it will do - it'll run in parallel (thanks to special run-p command) the static assets server - sirv public and a bundler in a watch mode: rollup -c -w. 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
It mean all went well so let's open localhost:5000 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 {name} in it.

Concerning the other files and app structure the sequence is as follows:

Other components -> App.svelte -> main.js

So app instance initialisation code is in the main.js file and since they're pretty simple it looks like this:

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

Form logic

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 Bootstrap form samples page.

So here's how your form may look like. No dynamic elements, just HTML markup.

Markup in Svelte is pretty easy, all the CSS, JS and HTML can be combined in one file (same you can do in Vue). 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 extension svelte-vscode that will manage code highlighting and many more for you.

Alt Text

State
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:


It is quite simple but later you may want to put it into Redux or persist in localStorage or what will you.

Form
Let's add a markup with using several Svelte features:

Let's see what are those:

  • {#if STATE.send.success} - way to show/hide certain blocks of markup based on the model value; {#}...{/} is a common way to structure templates in Svelte;
  • {@debug STATE} - 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;
  • on:click={validateAndSend} - Svelte way to bind event handlers on DOM element; in this case it's a button;

Sending data

In the JS logic the validateAndSend 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:

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

Building the app

Now if you see that the functionality that we expected is working as it should let's try to run the production build with: npm run build
Alt Text

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,


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 shershen08/feedbackform-svelte repo . 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: @legkoletat.

Discussion

pic
Editor guide
 

Thanks for this - however I'd suggest a few small improvements:

  1. Don't create an object called STATE, it's unneccessary. Store each variable as a simple top-level variable in your component, and then make your validation attributes (valid, etc) reactive (using $:). That way you don't need to call validateForm() or do any of the manual legwork.

  2. You don't need to use redux with Svele. It's totally unneccessary. Svelte has stores, which is a simple, powerful cross-component state model. However for local component state - just use variables, as mentioned above.

  3. One of the most important differences between Svelte and Vue/React is that it is compiled. It's probably worth mentioning this in your intro :)

 

Thanks for the detailed feedback Anthony. I would agree that using separate variables and adding reactive calculation could be a nice demonstration of this feature in Svelte.