Building Web Apps With Svelte
Tags: javascript, webdev, svelte
Published: 2021-02-04 18:09:50

## __Introduction__

When it comes to JavaScript frameworks, Svelte.js is considered _the new kid on the block_, but that does not mean it offers less. In this article you will learn some Svelte syntax and how you can set up a basic Svelte project, by the end of this article you should have enough confidence to approach advanced concepts in Svelte.

## What is Svelte

Svelte is a JavaScript compiler that is used to build a dynamic and interactive web app and user interface, this statement implies that Svelte will compile your code into a JavaScript implementation when you build for production. This is unlike regular frameworks and libraries where the core library is also shipped together with our code.

This is a good thing because apps built with svelte are much smaller in bundle size compared to apps built with other traditional frameworks.

Svelte syntax is easy to learn, short, and simple. In terms of Line of Code (LOC), what would take 10 to 15 lines of code in other traditional frameworks will take 5 to 6 lines in Svelte.

Syntax-wise, Svelte shares few similarities with React, therefore, if you have experience working with React, then learning Svelte will be easier.

## __How to install Svelte__

To install svelte on your computer you need to have Node.js installed, if you have Node.js installed, kindly skip the following otherwise, read the following guides based on your Operating System:

* [How to Install Node.js and NPM on Your Windows System](https://phoenixnap.com/kb/install-node-js-npm-on-windows)
* [Installing Node.js Tutorial: macOS - NodeSource](http://nodesource.com/blog/installing-nodejs-tutorial-mac-os-x/)
* [Installation of Node.js on Linux - GeeksforGeeks](https://www.geeksforgeeks.org/installation-of-node-js-on-linux/)

Once you've done that the next thing is to install a package from Node Package Manager called `degit`.

### __How to install `degit`__

Open your command line (or terminal) and perform the following steps:

* Type `npm i degit -g` and hit enter on your keyboard. This will install `degit`

### __Why install `degit`?__

The reason is simple: `degit` makes it easy to clone a Git repo,  and it will help you clone the Svelte template from its repo. Once `degit` is installed, you need to clone the starter template from the Svelte repo.

### __How to clone Svelte starter template__

You can perform the following steps to clone the Svelte starter template:

* Open up you command line (or terminal).
* Type `degit sveltejs/template svelte-app` and hit enter.

The second step will clone the Svelte template to your computer into a folder called `svelte-app`. Mind you, you don't have to call it `svelte-app`, you can use any name that pleases you.

You should know that whatever name you pass to `degit` command, a folder will be created with that name and the content of the Svelte starter template will reside in that folder.

Once it has finished downloading, perform the following steps (on the command line):

* Type `cd svelte-app` and hit enter

Next thing is to install the dependencies because the Svelte starter template that you cloned earlier does not come with the Svelte compiler and other dependencies. Still on the command line and inside the folder `svelte-app` type the following:

* `npm install` and press enter.

This might take a while, once the installation completes, your folder structure should look like the following:

```html

-----------------------------------------/node_modules
							|
    						|------------/src/
							|
							|------------/scripts/
							|
    						|------------README.md
							|
    						|------------/rollup.config.js

```

Here is a breakdown of the folder structure:
* The `node_modules` folder contains Svelte and its dependencies.
* The `README.md` file contains useful information about running the app.
* The `rollup.config.js` file is a module bundler much like Webpack.

This is our basic folder structure right now, next, we'll examine the `src` folder. 

```html

src/-------------------------------------/App.svelte
							|
    						|------------/main.js
							
```

The `src` folder contains two files namely:

* `App.svelte`
* `main.js`

### __`App.svelte`__

The `App.svelte` is a Svelte component that comes with the basic Svelte template (note the `.svelte` extension). All Svelte components must end with the `.svelte` extension, this allows the Svelte compiler to process such file.

### __`main.js`__

The main.js file is a file that kick-starts the Svelte app, it imports the App component from the `App.svelte` file and initializes the component targeting `document.body` i.e. all the application content will be injected to the document's `body` tag. Inside this `src` folder, we'll write the applications code, and the necessary Svelte components.

The `public folder` is what is served to the browser when you are in development mode, and it contains the following files:

* `index.html`
* `global.css`

We can also store other stylesheets, fonts, icons, images and other assets that our app depends on in the public folder.

The `script` folder contains a `setupTypeScript.js` file that will enable you to use Typescript in your Svelte components.

The next thing is to serve up the app and see the basic contents, you'll need to do that from your terminal, make sure you are at the root level in the `svelte-app` folder, then type the following:

* `npm run dev` and hot enter

This spins up a local development server with live reload feature, open up your browser and navigate to `localhost:5000`, you should see the Svelte starter template.

## __Working with Svelte__

There are several ways to work with Svelte, in this section you'll learn about the following:

* Dynamic content injection
* Conditional Rendering
* Looping
* Multiple components
* Functions on events.

### __Dynamic content injection__

Svelte allows you to insert the value of a JavaScript variable in your HTML which the browser will render when you launch the application. This process is known as dynamic content injection. How would you do that? Well, let's find out.

Switch back to your editor, open up the `App.svelte` component and clear up the contents so that you have a blank file, type the following code into the file:

```html
<script>
	let hero = 'spiderman'
</script>

<main>
	<h2> { hero } </h2>
</main>

<style>
    h2{
        color: grey;
    }
</style>
```

In the preceding code, the `hero` variable value is inserted into `h2`. When you save your file and launch your browser, the browser should display a gray colored text which reads `spiderman`. Here is a further breakdown of the code:

* `script` tag where you write JavaScript.
* `main` that has an `h2` tag as a child element, we then use curly braces to dynamically inject the value of the `hero `variable inside the `h2` tag.
* `style` tag for adding styles to our components.

Most of our Svelte components will have these three tags; a `script` tag, a `main` tag (although you can use a `div` tag or any HTML tag), and a `style` tag.

You will agree with me that this is much simpler to understand and is easier to write compared to other front-end frameworks.

Moving on, what you've seen in the previous code is just one of the ways that you can show stuff in Svelte, there is another way, and it's called _conditional rendering_. As the name implies, the browser will render HTML elements based on "conditions" in your Svelte component.

### __Conditional Rendering__

Open up the `App.svelte` file and add the following code:

```html
<script>
	let hero = 'spiderman'
    let villain = 'Thanos'
    let showHero = false
    let showVillain = true
</script>
<main>
	{#if showHero}
    	<h2>{ hero }</h2>
    {/if}
    {#if showVillain}
    	<h2>{ villain }</h2>
    {/if}
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

When you intend to perform conditional rendering in Svelte, you use a pair of curly braces, and the `#` symbol followed immediately by the `if` keyword, and then a condition you want to evaluate, then you close up the `if` block by using another curly braces, and inside it, you use the forward slash followed immediately by the `if` keyword.

In between, you write the HTML template you would like to to render. Whether your template gets rendered depends on the result of your expression.  If the condition evaluates to `false`, it won't be added to the DOM, if it evaluates to true it gets added to the DOM.

Open up your browser, and view the results. You'll notice that `Thanos` is added to the DOM, while `spiderman` is not because `showHero` is `false` and `showVillain` is `true`.

When you see an `if` keyword, you might think: Where is the `else`? Well, that's possible in Svelte!. Update your code to match the following:

```html
<script>
	let hero = 'spiderman'
    let villain = 'Thanos'
    let showHero = false
    let showVillain = true
</script>
<main>
	{#if showHero}
    	<h2>{ hero }</h2>
    {:else}
    	<h2>No hero yet</h2>
    {/if}
    {#if showVillain}
    	<h2>{ villain }</h2>
    {:else}
    	<h2>No Villain yet</h2>
    {/if}
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

Save it and launch your browser, you should see the text: `No hero yet` and `Thanos` rendered by the browser. This is much like a normal `if/else` construct, the template in the `else` section is added to the DOM if the expression evaluates to `false`. Don't forget to add the colon before the `else` keyword.

Furthermore, you can use an `:else if` block rather than using two if statements. Let's see how you can do that, edit the `App.svelte` file and modify it as such:

```html

<script>
	let hero = 'spiderman'
    let villain = 'Thanos'
    let showHero = false
    let showVillain = true
</script>
<main>
	{#if showHero}
    	<h2>{ hero }</h2>
    {:else if showVillain}
    	<h2>{ villain }</h2>
    {:else}
    	<h2>No Hero or Villain yet</h2>
    {/if}
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

We can use the `:else if` statement to add another condition to the block, and if that condition evaluates to `true` the HTML will be added to the DOM, if it evaluates to `false`, the browser will not add it to the DOM.

Next, let's take a look at how you can repeat templates in Svelte.

### __Looping with Svelte__

Similar to other front-end framework, Svelte provide you a means to repeat a template. Let's take a hypothetical example that you have an array of _heroes_, and you'd like to repeat a template for each item in the array, in Svelte it's easy. Switch over to your `App.svelte` file and write the following:

```html
<script>
	let hereos = ['spiderman', 'Deadpool', 'Thor']
</script>
<main>
	{#each heroes as hero}
    	<h2>{ hero }</h2>
    {/each}
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

If you want to render the items in the array, you'll have to use a pair of curly braces and in between them, you write the `#` sign followed immediately by the `each` keyword, then the array name, in this case it is `heroes`, followed by the `as` keyword then a variable name that gets assigned to each item in the array. 

Thereafter, you write the variable name between another pair of braces inside an HTML tag, in this case, it's an `h2` tag. Now, save the file, and launch your browser, you should see a list of heroes displayed in the browser.

Furthermore, you can use the `:else` statement to display a default message when something goes wrong or the array is empty. Modify your `App.svelte` file as such:

```html
<script>
	let hereos = ['spiderman', 'Deadpool', 'Thor']
    let heroes2 = [];
</script>
<main>
	{#each heroes2 as hero}
    	<h2>{ hero }</h2>
    {:else}
    	<p>No hero in the list</p>
    {/each
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

Save it and launch your browser. The browser does not render anything on screen.

### __Multiple Components__

Writing all your applications code in a single file is not recommended, therefore, you need to split your code into multiple components and import them when they are needed.

For example, you can have a list item component that can be reused for any list, and you can import it into a parent component which will make use of the list item. To see in this action, perform the following steps:

* Edit your folder structure.
* Inside the `src` folder create a file and name it `Hero.svelte`

Then type the following into `Hero.svelte`:

```html
<script>
	let hereos = ['spiderman', 'Deadpool', 'Thor']
</script>
<main>
	{#each heroes as hero}
    	<h2>{ hero }</h2>
    {:else}
    	<p>No hero in the list</p>
    {/each
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

Go ahead and save it. Next, open `App.svelte` and make the following changes to it:

```html
<script>
	import Hero from './Hero.svelte'
</script>
<main>
	<Hero /> <!-- Or -->
    <Hero></Hero>
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

Save `App.svelte`, and launch your browser, the output is similar to what you've seen before however the code has changed. Let's look at a few talking points:

* You will notice that you didn't export anything in our `Hero.svelte` file, yet you could import it in `App.svelte`, this is because by default, Svelte exports every component you create, therefore, you don't need to do that.
* Secondly, the code has a self-closing tag to represent the component, but you are not limited to this, you could also use opening and closing tags.

### __Functions on Events__

Sometimes, your code might need to fire a function when a button is clicked or when a form is submitted. You can do that using Svelte `on:event={function}` where:

* `event` represents the event we are targeting 
* `function` represents a reference to the function you want to run when the event fires

Let's have a look at an example. Open `Hero.svelte` and make the following changes to it:

```html
<script>
	let hereos = ['spiderman', 'Deadpool', 'Thor']
    let logHeroes = () => console.log(heroes)
</script>
<main>
	{#each heroes as hero}
    	<h2>{ hero }</h2>
    	<button on:click={logHeroes}>log heroes</button>
    {:else}
    	<p>No hero in the list</p>
    {/each
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

Open your browser, you should see a button under each _hero_. Next, open your browser console and then click on the button, you should see the heroes list output to the console.

You should note that we did not call the function explicitly, rather we pass a reference to the function, this is because if we call the function explicitly, it will fire the code immediately the browser loads up, this is quite similar to a behavior in React.

When we pass a function reference to an event, we automatically take in the event object and use it afterwards as shown in the code below:

```html
<script>
	let hereos = ['spiderman', 'Deadpool', 'Thor']
    let logHeroes = (e) => console.log(e, heroes)
</script>
<main>
	{#each heroes as hero}
    	<h2>{ hero }</h2>
    {:else}
    	<p>No hero in the list</p>
    {/each
</main>
<style>
    h2{
        color: grey;
    }
</style>
```

Save it, launch your browser and click the button, you should see the event object along with the _heroes_ list in the console.

## __Conclusion__

This article has shown you how to set up and work with Svelte. Mind you, we've merely scratched the surface of what Svelte is capable of. I'll write more about Svelte in future post(s). Thanks for reading.