Hyperapp + Hyperapp-router: Create a movie-shopping-cart web app.
Tags: hyperapp, hyperapprouter, javascript, frontend
Published: 2018-08-15 13:25:55

---
title: Hyperapp + Hyperapp-router: Create a movie-shopping-cart web app.
published: true
description: learn hyperapp.js basics of virtual-DOM rendering, routing and state management by building a single page app.
tags: Hyperapp, Hyperapp-router, Javascript, frontend
---

Hi everyone, this is my first tutorial on dev.to, I'll love to share with you an awesome frontend development framework which I've been learning; Hyperapp JS.

We're going to be building a [movie shopping cart single page app](https://thobyv.github.io/Hyperapp-shopping-cart-demo/) to learn how to use some basic features of hyperapp which includes Virtual-dom rendering, routing and application state managment.

![screenshot-hyperapp-router-tutorial](https://thepracticaldev.s3.amazonaws.com/i/hux80q9k5reymj11aibz.JPG)
*screenshot*


Here's the [github repo](https://github.com/ThobyV/Hyperapp-shopping-cart-demo)  incase you would love to go straight to the code, and here is the [Live Demo](https://thobyv.github.io/Hyperapp-shopping-cart-demo/)  hosted on github pages. Go ahead and play with the buttons.

##Requirements

There is'nt much required to follow/complete this tutorial but a basic knowledge of hyperapp (the [quick documentation](https://github.com/hyperapp/hyperapp) has a really simple example for this), and also it would help to know the basics of Javascript's ES6 syntax.

**npm packages we will be installing** 

[Hyperapp](https://github.com/hyperapp/hyperapp) : a micro-framework for building modern web applications, it combines state management with a virtual DOM engine that supports keyed updates & lifecycle events - all with no dependencies.

[Hyperapp-router](https://github.com/hyperapp/router): the official routing package for hyperapp.

[Hyperapp-transitons](https://github.com/hyperapp/transitions): smooth animations for our components.

[Bulma](http://bulma.io/): flex-box based framework for css styling.


#Getting started

If you read through [hyperapp basics](https://github.com/hyperapp/hyperapp#getting-started), I suppose you already know about hyperapp state, actions and view concepts, but if you're still a bit confused; i got you buddy. 


**state**
state is basically just data associated with the views/components of a webapp or any other software. Any time you like a post on twitter and then the love-shaped icon becomes red, we can say you have changed it's state from white to red, other examples include data from an API presented in a list/grid of css cards, a user's username or profile picture used across many components. 

**actions**
As earlier said hyperapp provides us means to update or change the state data throughout all components in our app  using actions. In hyperapp **actions**  are functions a developer can create to do that. Hyperapp supports asynchronous actions and actions that produce side effects.

**views**
the view function automatically updates the virtual-DOM when there are changes in state based on how you want it to look like and renders our components. 


##setting up our project

We won't be covering setting up rollup or webpack & babel configs in this tutorial, it's quicker and easier to use this [hyperapp-rollup-babel-hyperapp-router] (https://github.com/ThobyV/hyperapp-rollup-babel-hyperapp-router) boilerplate. It contains dependencies/rollup module bundling configurations we need to develop/ship our app.

Let's run the following commands in terminal to clone the repo, navigate to the folder and the install all project dependencies from *package.json* and also add bulma packages for styling.

```
    git clone https://github.com/selfup/hyperapp-one
    cd hyperapp-one
    npm install
    npm install bulma bulma-slider bulma-switch bulma bulma-badge

```

run the command below and visit **localhost:8080** in your browser to view our app.

```
    npm start

```


Our boilerplate comes with **live reload** so the browser automatically refreshes our app to reflect any saves/changes we make in our code.


###Folder structure

We're not going to cover all the files/folders explanations in our project in this tutorial (I'm too lazy, no not now!).

But it's always good to explain the main folders/files which we will be using frequently in our project.

####`/src folders:` 

Inside the main folder `/src` you will find we have folders: 

**/state** with a *state.js* file.

**/actions** with *actions.js* file.

**/views/containers**  with lazy/container components files.

**/components** with regular components files. 

**/config** folder for any helper functions/files we want. It comes empty in this boilerplate.


####`/src files:` 

**index.js** to serve as entry file for our module bundler.


**routes.js** files for our routes and view function.


(We're very close to knowing in detail what every file does in a moment).


###Faking our Data.

Navigate to `src/config` folder and create a file `data.js` which will contain fake top-rated movie data, you can copy the data from [here](https://github.com/ThobyV/Hyperapp-shopping-cart-demo/blob/master/src/config/data.js)  and paste it in the `data.js` file.

In `styles` folder in the same location as `config` folder create another sass file with name `variables.sass` to customize bulma and declare our bulma packages.

Edit the `app.sass` file and add the following sass imports for our bulma packages:

```

@import "variables";
@import "node_modules/bulma/bulma.sass";
@import "node_modules/bulma-badge/src/sass/index.sass";
@import "node_modules/bulma-switch/src/sass/index.sass";
@import "node_modules/bulma-slider/src/sass/index.sass";

```


In `variables.sass` copy and paste the following styling/variables from [here](https://github.com/ThobyV/Hyperapp-shopping-cart-demo/blob/master/src/styles/variables.scss), you can customize it if you want, but to get the dark theme of our app etc we need to use this. Our `rollup` config includes a packages that compiles sass in our project.


###About JSX

We will be writing our components using `JSX`.

JSX is a language syntax extension that lets you write HTML tags interspersed with JavaScript. Because browsers don't understand JSX, we use a transpiler like `babel` to transform it into `hyperapp.h` function calls under the hood. 

##Now let's get to it!


###Set up our app state model.

The first thing we're going to do is to declare the state model which our app will use, navigate to path `src/state.js` and add this code:

```javascript

import { location } from "@hyperapp/router"


import  { data } from '../config/data'


export const state =  {
  location: location.state,    
  movies: data,
  movie_list: [],
  cart: [],
  range_value: 160,
  switch_value: false,
  cart_item_count: 0,
  cart_item_total: 0,
}

```

In this code, we import the hyperapp-router `location` api function as required by hyperapp and register it in our state object for routing purposes.

We also import our mock data from `config/` folder and then set it as our `movies` state value. In other cases we can get this data from anywhere; a json response from a server etc but here we just fake it as an already gotten response data. This is what our [fake data](https://github.com/ThobyV/Hyperapp-shopping-cart-demo/blob/master/src/config/data.js) looks like.

After that, we create an empty array which is then attached to our `movie_list` property, it's empty so we can fill it up with any kind of data we want, later we will use this to our advantage in a functionality in our app.

the `cart` state property is also an empty array that will contain any movie a user adds to cart using an `ADD_TO_CART` action we will define soon.

`range_value` will hold an integer value from the range slider element. Here the default value is 160.

`switch_value` will hold a boolean value of an html switch element.

`cart_item_count` will hold an integer value of the count of items in `cart` array.

`cart_item_total` will hold an integer value of the total price of items in `cart` array.

It's great to define our state object and it's properties/values as it serves as the data model for our application. Don't worry soon you'll see how everything links together.

###Mutating our state data using actions.

We have briefly explained state concept previously and declared our state model, 
next we need to navigate to our `actions` file, this is where we will be writing actions functions that can mutate our state data, only actions can mutate state data in hyperapp.

**let's go ahead and write our first action.** Add this code in `src/actions/actions.js:`

```javascript

import { location } from "@hyperapp/router"

export const actions = {

  location: location.actions,

  GET_ALL_MOVIES: () => (state) => ({ 

    movie_list: state.movie_list = state.movies,  
    
  }),

}

```

If you have read the basics of hyperapp then you already know what this code does, but better still let's explain it a bit;

we import and register our router api as usual, and create a function `GET_ALL_MOVIES()` which is passed our state store data, it mutates our initially empty `movie_list` state by copying the fake data from the `movies` state to it. Dont worry you will see why we are are not using the `movies` state instead in a bit.

**now let's add some other actions** in the action object for the functionality features of our app. In Hyperapp you can have as many actions as you want;

####`Add movie to cart` action:

```javascript

 ADD_MOVIE_TO_CART: (movie_id) => (state) => ({

    cart_item_count: state.cart_item_count += 1,

    cart:  state.cart.filter(movie => movie.id === movie_id).length>0
    ?
    Object.assign(state.cart, state.cart[state.cart.findIndex(obj =>
    obj.id === movie_id )].quantity ++ )
    : 
    state.cart.concat(state.movies.filter( movie => movie.id == movie_id).map(res =>
    ({ movie_title: res.title,
       price: res.price, 
       movie_poster: res.poster_path, 
       total: res.price,
       quantity: 1,
       id: res.id }) )),

    cart_item_total: state.cart.reduce( (acc, cur) => {
    return acc + cur.price * cur.quantity;
    
    }, 0),

  }),

```
the action `ADD_MOVIE_TO_CART()` contains functions that modify the state property values they are assigned to. The functions are:

`cart_item_count` function increment's the `cart_item_count` state property value by adding 1 to it's current state value each time a movie object is added into the state `cart` array. It is called each time the `ADD_MOVIE_TO_CART` action is called.

`cart` function adds a movie object into the state `cart` array  from our state. Since actions have access to state, and can also be passed payload(data) from our components, we use Javascript's `.filter()` function on our `movies` state data to return the movie object from it's array whose `id` is same as the movie id passed from the movie component and return a boolean value so we can check if it is already present in the array or not.

If it is present then we just only increase the movie's `quantity` property by `1` 
but if it isn't present we locate the movie using it's id in the `movies` state array and then copy it's properties into the `cart` state array along with some new properties to help us create a `quantity` and a `total` property/value.

`cart_item_total` function calculates the total price of the movies in the `cart` array.

**Note:** we are using JavaScript's `.filter(), .concat(), .map(), .reduce()` functions when mutating state data in hyperapp because they are pure functions that do not modify an array but instead return a new array after an operation.


####`Filter movies by price range and shipping` actions: 

```javascript

FILTER_BY_PRICE: (event) => (state) => ({ 

    range_value: state.range_value = event.target.value,   
 
    movie_list: state.movie_list = state.movies.filter( movies => 
      state.switch_value ? 
      movies.price <=  state.range_value && movies.planet_shipping == true :
      movies.price <= state.range_value ),
  }),

  FILTER_BY_SHIPPING: (event) => (state) => ({

    switch_value: state.switch_value = event.target.checked, 
   
    movie_list: state.movie_list = state.movies.filter( movies => 
      state.switch_value ? 
      movies.price <=  state.range_value && movies.planet_shipping == true :
      movies.price <= state.range_value ),   
  }),

```

These actions are called by the range slider/switch `html elements` in our components, you can see how hyperapp renders state changes/updates the DOM quickly as the values are updated/changed.

We pass the values as event data from the range slider or switch element depending on which is used. 

Remember we created a `movie_list` state array separate for these filtering operations, even though we are using pure functions for our operations, we do not want to modify the `movies` state array using  dynamic data like this because it would be difficult to filter it again after the merge.


##Rendering our state data/executing actions using hyperapp *View* function components.

With Hyperapp we can create **2** kinds of components (Components are pure functions that return a virtual-node).

[Regular components](https://github.com/hyperapp/hyperapp#components) are components that have access to hyperapp state and actions. I like to think of them as `container` components with which we manipulate state/actions.

[Lazy components](https://github.com/hyperapp/hyperapp#lazy-components) are components that do not have access to/cannot mutate state and actions. I like to think of them as `presentational` components where we just pass our state values as properties for `styling`, `re-use` , `applying behaviours` etc in our views.


###Creating our components.


####`<App/>` component.

The first component we are going to create is the `App.js` component. It is a lazy/container component that would be rendered as our root `/` route component when a user visits our app. It calls the `GET_ALL_MOVIES()` actions from our `actions` api when it is created.

**Navigate to** `src/views/containers/App.js` and add this code.

```javascript

import { h } from 'hyperapp'
import { Link, Route, location, Switch } from "@hyperapp/router"

import { NavBar } from '../../components/NavBar'
import { MovieCard }  from '../../components/MovieCard'


export const App = () => ( state, actions ) =>


<div oncreate= { () => actions.GET_ALL_MOVIES() } >

      <NavBar cart_count= {state.cart_item_count}/> 

<section class="section">
<div class="container">    
<div class="columns">
<div class="column  is-3">    

    <div class="box">
    <div class="content">   
    <b> Highest Price: ${state.range_value} </b>
    <input   
    type="range" 
    oninput = { (event) => actions.FILTER_BY_PRICE(event) }    
    onchange = { (event) => actions.FILTER_BY_PRICE(event) }                          
    class="slider is-fullwidth is-small is-circle" 
    step="0.1" min="0" max="150" 
    value = {state.range_value}  />
    </div>

    <h1 class="title is-6 has-text-white"> Only show mars shipping movies</h1>

    <div class="field">
    <input id="switchMovie"
     type="checkbox" 
     name="switchMovie" 
     class="switch is-success" 
     checked={state.switch_value}
     onchange= { (event) => actions.FILTER_BY_SHIPPING(event) } />
     <label for="switchMovie"></label>
 
     </div>

    </div>

    </div>  

<div class="column  is-9">    
<div class="columns is-multiline is-mobile">

  { state.movie_list &&
    state.movie_list.map(
   ({ id, title, poster_path, price, vote_average, planet_shipping, overview, release_date }) =>

<div className="column  is-half-mobile is-one-third-tablet is-one-third-desktop is-one-quarter-widescreen is-one-quarter-fullhd">


      <MovieCard movie_id = {id}
                 title = {title } 
                 poster = {poster_path }
                 price = {price}
                 rating = {vote_average}
                 planet_shipping = { planet_shipping } 
                 plot = { overview }
                 release_date = {release_date }  /> 
        
          </div>  
                  )

  } 

</div>
</div>
</div>
</div>
</section>

     </div>   
 
 
```

Here we import hyperapp `h` function to transform our components written in `JSX` to virtual-Dom nodes.

Also we import [hyperapp routing api functions](https://github.com/hyperapp/router) from the installed `hyperapp-router` package.

We then import two `regular/presentational components` which we will create next for the purpose of  styling and etc. (it's often good practice to do this, it encourages code reuse).

Then we create a function that creates the App.js component and add a `hyperapp life-cycle` event which calls our intially created `GET_ALL_MOVIES()` action from our hyperapp actions when the App.js component is created in the DOM. Checkout [hyperapp life-cycle events](https://github.com/hyperapp/hyperapp#lifecycle-events)

Then we create a function using jsx and the `&&` operator in javascript to check the state store if `state.movie_list` has any data and executes Javascript's `.map()` function to each of the items in the movie_list array which in this case is our fake, top-rated movies data. Remember we talked about creating a presentational component soon, inside the `.map()` function we pass data from the returned objects into  the component which we will call `<MovieCard/>`  to style each object item as a component on it's own.

Also you can see our `range slider` and `switch` elements and how they have access to their respective state data properties and also how they call `actions` and pass `payload` event data to them. Note the kind of javascript DOM event listeners attached to each of the elements.

The rest is just responsive/grid styling thanks to the awesome bulma.



####`<MovieCard/>` component.

**Navigate to** `src/components` and create a `MovieCard.js` file and add this code, this will be a normal component child of the lazy component `App.js`.

```javascript

import { h } from 'hyperapp'
import { Enter } from "@hyperapp/transitions"
import { Link, Route, location, Switch } from "@hyperapp/router"

export const MovieCard = ({ movie_id, title, poster, price, rating, planet_shipping, plot }) => (

<div>

<Link to={`/details/${movie_id}`} >

 <Enter time={200} easing="ease-in-out" 
        css={{opacity: "0", transform: "scale(1,1)"}}>

    <div class="box">
    <div class="media">
    
    <div class="media-content">

      <div class="content">
      <span class="badge is-badge-warning is-badge-large" data-badge={rating}></span>
      </div>

       <div class="content">
       <p class="title is-6 has-text-light"> {title} </p>
       </div>

        <div class="content">
       <div class="tags has-addons">
         { planet_shipping &&
         <span class="tag is-success">ships to mars</span>  } 
        </div>
        </div>


       <div class="content">
       <figure class="image">
       <img src={`http://${poster}`}/>
       </figure>
       </div>
      

      <nav class="level is-mobile">
    
            <span class="level-item"> 
            <b> ${price} </b>
             </span>
        

      </nav>
      </div>


    </div>
    </div>

    
    </Enter>
    </Link>
</div>
    )

```

Here we import the same packages as before and a new `{ Enter }` component from the     `hyperapp-transitions` package which we will use to create a nice,smooth animation for our `moviecard` component.

Also we use the `<Link/>` component from the hyperapp router which we will use to open a modal route where a user can see more details of a selected/clicked movie card.

The most important thing to note is that we pass the movie data as properties from our `App.js` lazy component to our normal component, the rest of the code just covers some styling of the data from our properties like `{title}` which is the movie title, `{poster}` is the movie poster url, `{price}` is the movie price and `{planet_shipping}` is the boolean value true/false which we will use to check if a movie ships to mars or not.

You can see how we apply some logic using the `&&` operator to render an element conditionally after we evaluate the `{planet_shipping}` property. You can use `if/else` or even the `?` operator if you like but i prefer the `&&` operator as it best suits this sort of simple evaluation for me.   

The rest of the code is just styling.


####`<ViewMovieDetails/>` component.

Now we need to create a container component `<ViewMovieDetails/>` that will be rendered by `hyperapp-router` when the user selects a movie, it displays more information about the movie. It's route path is `/details/:movie_id`. Do take note of the special `:movie_id` term after the route path, it's just a parameter which the router package uses to grab the `id` property from our selected movie object in the previous component and pass it as a route parameter in the url for this component to use.

In `src/views/containers/` create a `ViewMovieDetails.js` file and add the code

```javascript

import { h } from 'hyperapp';

import { MovieDetails  } from '../../components/MovieDetails'


export const ViewMovieDetails = ({match}) => (state, actions) => (

<div> 


{ 
   
    state.
    movie_list.
    filter( movie => movie.id == match.params.movie_id ).
    map( ({ id, title, overview, poster_path, vote_average, release_date , price }) => 

    <MovieDetails 
        cart_count={state.cart_item_count}
        id={id}
        title={title}
        plot={overview}
        poster={poster_path}
        price={price}
        rating={vote_average}
        release_date={release_date}
        addAction={  () => actions.ADD_MOVIE_TO_CART(id) }
        />
     
    )
  } 
</div>
)

```

As always we import the pnormal component called `<MovieDetail/>` for presentational use as a child component (we will create it shortly) and then we filter through `movie_list` state array to find a movie whose `id` is equal to id passed from the route and then applying `.map()` function to the result data as the  `<MovieDetail/>` component which is then passed it's necessary properties which also includes an action `ADD_MOVIE_TO_CART()` and state value of the `cart_item_count`.



####`<MovieDetails/>` component.

Now let's create the child component of the `<ViewMovieDetails/>` lazy component.

In `src/components/` folder create a file `MovieDetails.js` and add this code:


```javascript

import { h } from 'hyperapp'


export const MovieDetails = ({ cart_count, id, title, addAction, poster, price, rating, release_date, plot }) => (
    <div>
          <div class="modal is-active">
          <div class="modal-background"></div>
          <div class="modal-card">
          <header class="modal-card-head">
          <p class="modal-card-title">{title} </p>
          
          <button class="delete" aria-label="close"  onclick= { () => { window.history.back() }}></button>
          </header>
          <section class="modal-card-body">

          <div class="columns">

          <div class="column">

         <figure class="media-left">
        
         <img src={`http://${poster}`} />      
        
         </figure>
         
          </div>

          <div class="column">
          <p class="title is-5 has-text-white"> Plot: </p>
          <p class="title is-6 has-text-white"> {plot} </p>
          
          <p class="title is-6 has-text-white">Release date {release_date} </p>  
          <span class="tag is-warning">{rating}</span>
          
            
          </div>
          </div>

    </section>
    <footer class="modal-card-foot">
     
    <a class="button is-success" onclick={ addAction }> 
    <b>  Add to Cart  ${price}  </b>
    </a>
    <b> {cart_count} Items in cart</b>  
    

    </footer>
  </div>
</div>

    </div>
        )

```

here we recieve properties `cart_count`, `price` e.t.c from the `<ViewMovieDetails/>` component and then add some styles to it. Remember we passed and action responsible for adding a selected movie to cart when the button onclick event is fired as `{addAction}` and the number of total items in the cart as `{cart_count}`.



####`<ViewCart/>` component.

Now let's create a lazy component that will be rendered when a user visits `/cart` route. In this component we will display movies which have been added to cart by the user.

In `src/views/containers/` add a file `ViewCart.js` and add this code;

```javascript

import { h } from 'hyperapp';

import { CartItems } from '../../components/CartItems'
import { NavBar } from '../../components/NavBar'



export const ViewCart = ({match}) => ( state, actions ) => (
   
    
<div>

    <NavBar cart_count= {state.cart_item_count}/> 

<section class="section">
<div class="container">    

             <p class="title is-3 has-text-white"> Cart Items </p>

{
    state.cart.filter(res => res.id )
    .map( res => 
    
        <CartItems movie_id={res.id}
        title={res.movie_title}
        price={res.price}
        quantity= {res.quantity}
        total= {res.quantity * res.price }
        poster= {res.movie_poster}
        />


    )

    
}
    { <p class="title is-5 has-text-white"> total price: ${state.cart_item_total}  </p> }


</div>
</section>
</div>

)



```

In this code we have the `<NavBar/>` imported and used and also we mapped through items that are in our state's cart array and passed the results to it's child  component `<CartItems/>.`


####`<CartItems/>` component.


Now let's create the `<CartItems/>` component. 

In `src/components` create a file `CartItems.js` and add this code:

```javascript

import { h } from 'hyperapp'

export const CartItems = ({ movie_id, title, price, quantity, total, poster }) => (

    <div>

         <article class="media">

         <figure class="media-left">
         <p class="image is-64x64">
         <img src={`http://${poster}`}/>      
         </p>
         </figure>

         <div class="media-content">
         <div class="content">

            <p class="title is-5 has-text-white"> {title} </p>

            <small> ${price} x </small> 
            <b>{quantity} copies</b>

            <p/>

            <small> Total price: </small> <b> ${total}</b>
            
            <hr/>
            
         </div>
         </div>

          </article>

    </div>
        )

```

I assume this component is self-explanatory, it just styles the properties passed to it from it's parent component `<ViewCart/>` and applies some behaviour to it.


####`<NavBar/>` component.

And then finally the NavBar component.

Navigate to `src/components` and create a `NavBar.js` file and add this code so we can create a nice navigation bar that would hold links to other components and recieve the cart's items count data from any parent lazy component where it is used.

```javascript

import { h } from 'hyperapp'

import { Link, Route, location, Switch } from "@hyperapp/router"

export const NavBar =  ({cart_count}) => (
<nav class="navbar is-primary has-shadows" role="navigation" aria-label="main navigation">
<div class="navbar-brand">

<a class="navbar-item" href=""> 
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" 
viewBox="0 0 133.80357 132.29168"><g transform="translate(-37.57 -49.048)"><rect width="132.292" height="90.714" x="38.554" y="90.625" ry="9.719" fill="#edc905" paint-order="stroke fill markers"/><rect width="5.292" height="61.988" x="12.631" y="72.602" ry="1.911" transform="rotate(-34.65)" fill="#edc905" paint-order="stroke fill markers"/><rect transform="rotate(-145.35)" ry="1.911" y="-39.86" x="-154.078" height="61.988" width="5.292" fill="#edc905" paint-order="stroke fill markers"/><ellipse cx="148.923" cy="115.949" rx="7.56" ry="7.182" paint-order="stroke fill markers"/></g></svg>
</a>

<Link to="/cart" class="navbar-item">
<span class="badge is-badge-danger is-badge-medium" data-badge={cart_count}>
<svg xmlns="http://www.w3.org/2000/svg" 
width="25" height="25" fill="#FFFFFF" 
viewBox="0 0 8 8">
<path d="M.34 0a.5.5 0 0 0 .16 1h1.5l.09.25.41 1.25.41 1.25c.04.13.21.25.34.25h3.5c.14 0 .3-.12.34-.25l.81-2.5c.04-.13-.02-.25-.16-.25h-4.44l-.38-.72a.5.5 0 0 0-.44-.28h-2a.5.5 0 0 0-.09 0 .5.5 0 0 0-.06 0zm3.16 5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm3 0c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5z"
transform="translate(0 1)" />
</svg>
</span>
</Link>
</div>

</nav> )

```

we create navigation bar component with a `cart_count`  property  to display the amount of items we have in our cart.



###Registering our lazy components to their respective route paths.

Now that we have created all necessary components for our app, the next thing we need to do is register the parent/lazy components as route components so the hyperapp `View` function can return their respective virtual nodes and watch for state changes aka rendering UI. We are using `hyperapp-router's <Switch/>` component to declare multiple `route paths` and their respective components to render when the route path is visited.

```javascript

import { h } from 'hyperapp'
import { Link, Route,location, Switch } from "@hyperapp/router"


import { App } from './views/containers/App'
import { ViewMovieDetails } from './views/containers/ViewMovieDetails'
import { ViewCart } from './views/containers/ViewCart'



export const view = ( state, actions ) => 

<div>

<Switch>    
    <Route path="/" render={ App } />   
    <Route path="/cart" render={ ViewCart } />         
    <Route path={ "/details/:movie_id"} render={ ViewMovieDetails} />
  </Switch>

</div>


```

[checkout hyperapp-router docs to learn more about routing in hyperapp](https://github.com/hyperapp/router), 


###Connecting everything.

Now we need to mount our entire app to the DOM, hyperapp requires us to do this in an `index.js` file, this file serves as an entry file for `rollup` or any other module bundler to bundle our entire application codes into a single javascript file.

Let's add this code in the `/index.js` file;

```javascript

import { h , app } from 'hyperapp'

import {  location } from "@hyperapp/router"

import { state }  from './state/state'
import  { actions } from './actions/actions'
import { view }   from './routes'


import  './styles/app.scss'


const main = app(state, actions, view, document.querySelector('.hyperapp-root'))

const unsubscribe = location.subscribe(main.location)

```

Here we import the needed hyperapp api functions and also our `state, actions` and `view` files which we then mount to the DOM using hyperapp's `app` function. We have also imported our sass file so it can be compiled too when our module bundler package processes the `index.js` file. The processing includes transpiling our JSX/ES6 syntax using babel, [treeshaking](), compiling sass to css e.t.c.

#That's it!

We have finished our project for this tutorial, I suppose you have been checking our progress gradually in your browser at **localhost:8080** to see our final output.

You can run a production build and deploy to github pages or whatever static file server you want so you can share  with others. There is a tutorial on this if this is your first time.

Thank you so much for reading, I'm very much interested in any opinions to correct or report errors, or suggest anything that would make this tutorial better as I am looking to improve. You can visit the [project repo](https://github.com/ThobyV/Hyperapp-shopping-cart-demo) on github. Feel free to open issues!