DEV Community

Eternal Dev for Eternal Dev

Posted on • Originally published at eternaldev.com on

Getting Started with Svelte by building a landing page

Introduction

Svelte helps in building web applications using HTML, CSS and Javascript. Unlike React, Svelte doesn't have Virtual DOM or any other abstraction on top. It acts as a compiler that spits out vanilla Javascript. This means that Svelte is added as a dev dependency and results in faster execution speed of the application

Originally published at (https://www.eternaldev.com/blog/getting-started-with-svelte-by-building-a-landing-page/)

Getting started with Svelte

You can use the following command provided to get a copy of the template and start working

npx degit sveltejs/template comapny-landing-page
cd comapny-landing-page

# to use TypeScript run:
# OPTIONAL to run the following command
node scripts/setupTypeScript.js
Enter fullscreen mode Exit fullscreen mode

It is optional to run the setupTypeScript.js file which will set up the project to use TypeScript instead of Javascript. If you are not familiar with TypeScript, you can skip this step.

I feel like it is easier to start with Svelte after learning the basics of HTML, CSS, and Javascript.

Install the dependencies and start the project

npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Prerequisites

  1. Basic understanding of HTML, CSS, Javascript
  2. Familiarity working with Node ecosystem

In this article, we don't discuss in-depth about the CSS properties used to make the design. If you are not familiar with any of the CSS properties, you can reach out to me

Landing page design

Building a landing page for your personal website can be a good way to start your dev journey. It mostly has static content and the focus will be on building the layout and styles

Design1.PNG

Simple landing screen showcasing a product with a call to action button

Design2.PNG

Adding a footer at the bottom of the design

We can divide the design into four component

  1. Top Menu bar
  2. Call to Action Content
  3. Features List
  4. Footer

First Svelte component

From the template, we will have a couple of files which are of interest.

  1. main.ts - The starting point of the app
  2. App.svelte - First Svelte component
import App from './App.svelte';

const app = new App({
    target: document.body,
    props: {
        name: 'world'
    }
});

export default app;
Enter fullscreen mode Exit fullscreen mode

Inside the main.ts file, we are importing the Svelte component and exporting it as a default. It is getting added to the document.body

Breakdown of Svelte 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>
Enter fullscreen mode Exit fullscreen mode

A component is divided into three parts

  1. HTML markup
  2. Script
  3. Styles

You can directly start typing the HTML markup on the file and svelte will render that in the DOM

Scripts are added inside the . You can have Javascript code that controls the component here.

Note: Svelte has native support with Typescript as well and running the script at the start of the template makes all the .js files to .ts files.

Finally, CSS are added into the

This feels very familiar for anyone who has worked with HTML

index.html and global CSS styles are present inside the build folder from the template

Building the top menu

After learning the basics of Svelte, let's start by building the Top Menu component. It is easy to split your codebase into multiple small components.

We will create a new file and import that file into the App.svelte

Create a new folder called components and create a file called Menu.svelte

Convention is to use a Capitalized name for your component names to differentiate it with HTML Elements

<nav role="navigation">
    <div class="left_div">
        <a href="/">Company Name</a>
    </div>
    <div class="right_div">
        <a href="/">Blog</a>
        <a href="/">Pricing</a>
        <a href="/">About Us</a>
    </div>
</nav>

<style>
    nav {
        display: flex;
        background-color: #363062;
    }
    nav a {
        color: white;
        padding: 0 0.5rem;
        font-weight: bold;
    }

    nav a:hover {
        text-decoration: none;
    }

    nav div {
        flex: 1;
        padding: 1rem;
    }
    .right_div {
        text-align: right;
        background-color: #827397;
    }

</style>
Enter fullscreen mode Exit fullscreen mode

CSS Scopes

If you are already familiar with using CSS in other frameworks, you might look at the above styles and think, adding styles directly to div is not the best way as it would affect your other components. Although I will agree with your point, Svelte helps in keeping these styles only specific to the component.

One of the nice features of Svelte is that the CSS inside the component is scoped to only affect that component. This means that your styles are not leaked outside the component.

This makes it very easy for writing styles inside the component and not to think about how it will affect the rest of the application.

Let's add the component to the App.svelte

<script lang="ts">
    import Menu from './components/Menu.svelte';
</script>

<Menu />

<style>
    :root {
        font-family: sans-serif;
        padding: 0;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Code is very simple to import the Svelte component and then add it as part of the HTML markup

Main content with Image

Adding the main content to the page as per the design will follow the same steps as above. Creating a new file and importing it into the App.svelte

<script lang="ts">
    export let CTA_Name: string = "Click Here";
</script>

<main>
    <div>
        <h1>Landing page</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac dui iaculis, condimentum sapien ac, interdum libero. </p>

        <button>{CTA_Name}</button>
    </div>
    <div class="right_side">
        <img src="images/mobile_cover.jpg" width="100%" alt="Mobile diplay"/>
    </div>
</main>

<style>
    main {
        display: flex;
        flex-direction: row;
        color: white;
    }

    div {
        padding: 2rem;
        flex: 1;
        background-color: #363062;
    }

    .right_side {
        background-color: #827397;
    }

    img {
        box-shadow: 0px 4px 10px #333;
    }

    button {
        margin-top: 2rem;
        min-width: 200px;
        border-radius: 2rem;
        background-color: #827397;
        color: white;
        font-weight: bold;
        font-size: 1.2rem;
        border: 0px;
        box-shadow: 2px 4px 5px black;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Passing props to the component

Most of the components will require data to be passed in from a higher-level component. We can achieve this by using the props in the component. It is very simple to create props. Just add it as a variable in the scripts like the example below

<script lang="ts">
    export let CTA_Name: string = "Click Here";
</script>
Enter fullscreen mode Exit fullscreen mode

Here we are exporting the variable CTA_Name which will act as a prop. We can also assign a default value for the prop if it is not provided.

To send data to the prop, you can update the App.svelte to pass the variable

<script lang="ts">
    import Menu from './components/Menu.svelte';
    import Main from './components/Main.svelte';
</script>

<Menu />
<Main CTA_Name={"Get Started"}/>
Enter fullscreen mode Exit fullscreen mode

Creating the features component

For the Features, we have created a TypeScript type call FeatureType and added the model inside it.

<script lang="ts">
    type FeatureType = {
        id: number;
        heading: string;
        content: string;
        img: string;
    };
    export const articles: FeatureType[] = [
        {
            id: 1,
            content:
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac dui iaculis, condimentum sapien ac, interdum libero.",
            heading: "High Resolution Camera",
            img: "images/mobile_cover.jpg",
        },
        {
            id: 2,
            content:
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac dui iaculis, condimentum sapien ac, interdum libero.",
            heading: "Blazing Fast Processor",
            img: "images/mobile_cover.jpg",
        },
        {
            id: 3,
            content:
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac dui iaculis, condimentum sapien ac, interdum libero.",
            heading: "Long Lasting Battery",
            img: "images/mobile_cover.jpg",
        },
    ];
</script>

<div class="features">
    {#each articles as article (article.id)}
        <div class="feature">
            <h3>{article.heading}</h3>
            <img width="60%" src={article.img} alt={"Mobile content logo"} />
            <p>{article.content}</p>
        </div>
    {/each}
</div>

<style>
    .features {
        display: flex;
        justify-content: center;
        gap: 10px;
        padding: 4rem;
        text-align: center;
    }
    img {
        clip-path: circle(50px at center);
    }
    .feature {
        flex: 1;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Handling callback from the component

Components can provide events to the parent. This can be achieved using createEventDispatcher and passing the custom event needed from the child component.

In this example, we will have a button "Scroll to Top" in the footer which will pass the event to the parent. The parent component can handle the function of how to scroll the page.

We are not passing any extra data in the event, but that can also be done easily by passing an object when calling the dispatch method.

<script lang="ts">
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    const onBackToTop = () => {
        dispatch('scrollToTop', {});
    }
</script>

<footer>
    <div>
        <h3>Summary</h3>
        <h5>About Us</h5>
        <h5>Blog</h5>
        <h5>Pricing</h5>
    </div>

    <div>
        <h3>Social Links</h3>
        <h5>Facebook</h5>
        <h5>Twitter</h5>
    </div>

    <div>
        <h3>Blog</h3>
        <h5>How to select a phone ?</h5>
        <h5>Why is our company phone better ?</h5>
        <h5>Top 10 budget phones to buy in 2021 ?</h5>
    </div>

    <div>
        <button on:click={() => onBackToTop()}>Scroll to Top</button>
    </div>
</footer>

<style>
    footer {
        display: flex;
        justify-content: space-around;
        background-color: #363062;
        color: white;
    }

    footer h3 {
        text-transform: uppercase;
    }

    footer div {
        padding: 5rem 2rem;
    }

    footer button {
        margin-top: 1rem;
        min-width: 120px;
        border-radius: 2rem;
        background-color: #827397;
        color: white;
        border: 0px;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Once the child component has defined the custom event, the parent component can listen to the event and perform any action needed.

Here on the Footer component, we have on:scrollToTop event which will call the scrollToTop function.

<script lang="ts">
    import Menu from './components/Menu.svelte';
    import Main from './components/Main.svelte';
    import Features from './components/Features.svelte';
    import Footer from './components/Footer.svelte';

    const scrollToTop = () => {
        scrollTo({top: 0});
    }
</script>

<Menu />
<Main CTA_Name={"Get Started"}/>
<Features />
<Footer on:scrollToTop={() => scrollToTop()}/>
<style>
    :root {
        font-family: sans-serif;
        padding: 0;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Summary

This article covers building a quick landing page using Svelte. If you have any questions or feedback feel free to reach out on our Discord server.

Stay tuned by subscribing to our mailing list and joining our Discord community

Discord

Discussion (0)