Building a Full Stack Application From Scratch with Svelte and Node (PART 2) — Displaying Stories

Nov 21 2019 | By Taha Shashtari

After we created a new Sapper project in the previous part, let's prepare our project and display some stories on the homepage.

How routing works in Sapper?

The docs explains that in detail, but for now all you have to know is that you can view your components in the browser if you create them inside src/routes. If, for example, you have src/routes/hello.svelte, you can go to http://localhost:3000/hello and see it rendered there.

Instead of listing every possible case the router can handle, I'll explain the ones we need as we're working on the app. You'll notice that this is the theme I'm following throughout this series.

Removing the example files

Before we begin working on our app, let's remove the example routes and components that come with newly created Sapper projects.

Here are the files to remove:

  • src/routes/blog/ (remove the whole directory)
  • src/routes/about.svelte
  • src/components/Nav.svelte

And then delete the content of index.svelte.

Cleaning up src/routes/_layout.svelte

We will add the Nav and the LoadingBar components to this file later. But for now let's replace the content of this file with this:

<main>
    <slot></slot>
</main>

Where should we put our components?

We should store app-specific components separately from UI general-purpose components — I wrote an article explaining the difference between them.

For this app, we would only have a single UI general-purpose component and we would create it in src/components/ directory.

For all other components (app-specific components), we'll add them inside src/routes/ directory. If the component we're creating is used in multiple routes, we'll add it to src/routes/_components/ directory — we don't have this directory, so let's create it.

Note that we have to prefix components with an underscore so it wouldn't be treated as a route. So if you try to open http://localhost:3000/components/YourSvelteComponent in the browser, you'll get a 404 page.

The workflow of displaying stories

First we'll create the component of a single story — we'll name it Story. And in that component, we'll use some mocked data (since we don't have the backend server yet).

Instead of displaying the Story component directly on the homepage, we'll display it inside another component called Stories.

The Stories component will work as a list component. We need this component to handle loading stories, pagination, sorting, etc.

And then we'll display the Stories on the homepage.

Creating the Story component

As we're working through this series, this component will become more and more sophisticated, but for now let's start with this simple markup and mocked data.

So create src/routes/_components/Story.svelte and put this:

<script>
  let story = {
    score: 0,
    title: 'First Story',
    user: {
      username: 'user'
    },
    link: '/',
    commentsCount: '2 comments',
    createdAt: '2 days ago'
  }
</script>

<div class="homepage page">
  <div class="story-item">

    <div class="voter">
      <span class="upvoter">
        <span class="arrow"></span>
      </span>
      <span class="score">{story.score}</span>
    </div>

    <div class="main">
      <div class="details">
        <a
          class="title"
          href="{story.link}"
        >
          {story.title}
        </a>
        <span class="domain">
          self
        </span>
      </div>
      <div class="byline">
        by {story.user.username} {story.createdAt} |
        <a
          class="comments-link"
          href="{story.link}"
        >
          {story.commentsCount}
        </a>
      </div>
    </div>

  </div>
</div>

Creating Stories list component

In this part, we won't be handling things like pagination and sorting. We just need to display a few stories inside this component.

So let's create src/routes/_components/Stories.svelte and write this:

<script>
  import Story from './Story.svelte'
</script>

<div class="story-list">
  <Story/>
  <Story/>
  <Story/>
  <Story/>
  <Story/>
</div>

Displaying stories on the homepage

Our last step is to display these stories on the homepage. So all we have to do is add <Stories/> inside src/routes/index.svelte.

<script>
  import Stories from './_components/Stories.svelte'
</script>

<div class="homepage page">
  <Stories/>
</div>

After this, you should see the stories displayed on the homepage like this:

What's next?

In the next part, we're going to create a route for displaying a single story. We'll also implement the comments section, in which you'll learn about nesting components recursively.