Obinna Ekwuno Writer of all things Technical and inspirational , Developer & Community Advocate. In a love-love relationship with JavaScript🔥.

How to build a simple Svelte JS app

(example included)

5 min read 1606

In the world of JavaScript, a new framework comes out every day and the idea behind such advancements are almost always the same but with a few very significant improvements. Modern component-based frameworks include ReactJS, VueJS, emberJS, Angular, and many more.

In this article, we will be looking at one of these new frameworks, known as SvelteJS. Which builds on the of the basic knowledge of HTML, CSS, and JavaScript, to give a unique and understandable approach to building platforms for the web.

Svelte serves as a middle ground, a way to get started with the fundamentals while getting used to modern concepts like component-driven development, scoped vs. cascading CSS, templating, declarative functions, etc.

Prerequisites

Before we go any further, this article assumes the following:

  • Node.js ≥v6 is installed on your machine
  • npm is installed on your machine
  • Familiarity with HTML, CSS, and JavaScript
  • A basic understanding of component-based frameworks like, ReactJS is good but not required

 

The difference between Svelte and component-based frameworks

Svelte is more understandable for those who are new to coding and it avoids getting lost in a world of hot reloads and components because it allows for application of DOM type manipulation. Svelte compiles all the generated files down to a single file (bundle.js). Svelte is a framework, meaning it doesn’t work with the virtual DOM but writes code that surgically updates the DOM when the state of your app changes.

Building a bookstore app with Svelte

Getting started

There are several ways to get Svelte up and running for a project. You can read more about the many ways to get started here. For the purpose of this article, we will be working with degit which is a software scaffolding tool. To start, run the following commands:

  • npx degit sveltejs/template {project name }: In this case I am calling it Book-app-svelte
npx degit sveltejs/template Book-app-svelte
  • Cd into project directory
  • Run npm install
  • Run the application by running npm run dev

svelte install

After setting up, in the main.js , we should see a “hello world” that renders into the app.svelte – this would be a good time to note that components in Svelte are saved with .svelte extension.

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

The above code shows a simple set-up with the app component accepting a prop of name and targets a place in the HTML file.

In the app.svelte we can see some sort of VueJS format:

<script>
    export let name;
</script>
<style>
    h1 {
        color: purple;
    }
</style>
<h1>Hello {name}!</h1>

This is where the main.js gets handled by exporting the name variables to allow it to be manipulated from outside.

Creating a dynamic book component

When creating our components, there are a few things that are noteworthy about SvelteJS:

  • Styles are scoped within components – so a h1 styled in one component will not affect another in a different component
  • We can define functions that are connected dynamically

In this section, we will be looking at creating a dynamic event with Svelte and linking the book.svelte component with app.svelte and passing props.

The first step is setting up the book component and exporting variables which can be set from the parent tag in app.svelte:

<script>
    export let bookTitle;
    export let bookPages;
    export let bookDescription;
</script>
<style>
    div{
        margin: 1rem;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26)
    }
    h1{
        font-size: 1.25rem;
        margin: 0.25rem 0;
    }
    h2{
        font-size: 1rem;
        margin: 0.25rem 0;
        color: aqua;
    }
    p{
        margin: 0.25rem 0;
    }
    button{
        font : larger;
        padding: 0.15rem 0.5rem;
        background-color: #1b1a1a;
        border: 1px solid  aliceblue ;
        cursor: pointer;
        color: white;
    }
</style>

<div>
    <h1> {bookTitle} </h1>
    <h2> {bookPages}</h2>
    <p> {bookDescription}</p>
    <button> Add </button>
</div>

From the code block above, we can see that we have variables that are being dynamically passed to the tags in the div . They have their values coming from the app.svelte which we will see next and where most of the dynamic manipulations happen.

In the app.svelte we have imported the book component and this is where we will do a lot of the dynamic manipulation.

<script>
    import Book from './book.svelte'
    let title = '';
    let pages = 0;
    let description = '';
    function setTitle(event){
        title = event.target.value;
    }
</script>
<style>
    h1 {
        color: purple;
        
    }
    section{
        margin: auto;
        width :30rem;
        
    }
    label,input,textarea{width: 100%}
</style>
<section>
    <div> 
        <label for="title">Title</label>
        <input type="text" id="title" value={title} on:input={setTitle}/>
    </div>
    <div>
        <label for="pages"> pages</label>
        <input type="number" id="price" value={pages} bind:value={pages}/>
    </div>
    <div>
        <label for="description">Description</label>
        <textarea rows="3" id="description" bind:value ={description}/>
    </div>
</section>
<Book bookTitle={title} bookPages={pages} bookDescription={description}/>

From the code example above, we can see that inside our script tag, we have also set variables to empty “ ”. These are the values that are automatically updated, we can also notice a function setTitle , this function is used to set a title to target the object that calls it within the on:.

Note that we call the function without parenthesis because we don’t want it immediately executed. Instead, we are trying to set up a refers so that Svelte can call the function on every keystroke.

We use the on: to add event listeners in Svelte. We can use this to listen to the input event, and the curly braces are used to show dynamic input. Since the function we have uses two-way binding, we can use it on other tags using the bind: This binds the value property then binds to the price variable. We also do this for the description.

Finally passing back to Book tag is the part where we update the props being exported in the book component. We do this by dynamically passing the values of title, pages, and descriptions using curly braces {}.

Displaying book information

Now that we have the card updating when we input value, the next step is to make sure that we are able to add books to our bookstore. The first thing we have to do is make our button a standalone component, in order to be able to use it in the other two components. We do this by creating a button.svelte and importing it to the book and app component respectively.

<style>
  button{
        font : larger;
        padding: 0.15rem 0.5rem;
        background-color: #1b1a1a;
        border: 1px solid  aliceblue ;
        cursor: pointer;
        color: white;
    }

</style>


<button on:click >
    <slot/>
</button>

You might notice an on:click attribute in the button tag, this is used to trigger the event listener in the original calling of the button so that other importations can be able to actually work with the onclick event.

Eg. : app.svelte

<Button on:click={addBook}>ADD Book</Button>

This engages with an addBook function that allows the button to add books dynamically to an array:

let books =[]

function addBook(){
        const newBook = {
            title : title,
            pages : pages,
            description: description
        };
        books = books.concat(newBook)
    }

The above code exists inside the script tag and what it does is, call all the properties of the book from the form and concatenates them. We make use of a concat because push does not change the book variable. It only changes the array but assigning concat to a new value with trigger a change.

We now have an array of books which is displayed conditionally using a special markup that Svelte gives us:

{#if books.length === 0}
    <p>
       Add a new book 
    </p>
    {:else}
    {#each books as book}
        <Book bookTitle={book.title} bookPages={book.pages} bookDescription={book.description}/>
    {/each}
{/if}

What this does is that it prompts the user to add new books then displays each new block as a new card:

bookstore form

And displays the information on the card once the user updates:
bookstore ui

 

 

Adding the price of books

To achieve this, we will have to make another component called purchase.svelte . In the script tag, we would want to export the books variable so that it can be updated by the book tag, by passing the information as props in the app.svelte.

In the app.svelte we add an empty array in the script to hold the purchased books. Now how do we add books to these purchases? We will use the buy button in the book component and then, add the purchaseBook function to script and bind to the button using on:{purchaseBook}.

We then use the create a dispatch function from the Svelte’s custom library.

Then we can link the function to the Book tag by adding the on:buy = {purchaseBook} This event dispatches from our purchaseBook function.

function purchaseBook(event){
        const selectedTitle= event.detail;
        purchases = purchases.concat({
            ...books.find(book => book.title === selectedTitle )
        });
    }

Conclusion

In this article, we have attempted to understand the basic use of Svelte by creating a book store demo. I hope this post helps you understand the power of SvelteJS and shows you the ways you can go about creating awesome applications. Here is a link to the demo. Happy coding! 😄

Plug: , a DVR for web apps

LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Obinna Ekwuno Writer of all things Technical and inspirational , Developer & Community Advocate. In a love-love relationship with JavaScript🔥.

Leave a Reply