Postix II: Multipage app with routing, in Hyperapp
In the last story, we set up a development environment for our app and created a simple “Hello World” example. In this story, we will extend our last work and turn it into a multipage app with a functioning router and page components.
Here is the links to the entire series;
Postix I : Starting with “Hello World” in Hyperapp
Postix II: Mutipage app with routing, in Hyperapp ( < you are here)
Lets pick up from where we left off. Make sure you have the codebase from Part 1.
We will be using a Hyperapp module @hyperapp/router. Install the module with npm i --save @hyperapp/router
Now, let us define some simple pages in our src/pages
folder.
Add in a Home.js
file with the content;
import { h } from "hyperapp";
const Home = h("h1", {}, "Home")
export default Home
and a src/pages/About.js
file with the content:
import { h } from "hyperapp";
const About = h("h1", {}, "About")
export default About
The Home page will show a simple H1 tag as <h1>Home</h1>
and the About page will show <h1>About</h1>
after the rendering is done.
Now we will create a Layout inside which our Home and About pages will be rendered. Add a new file src/components/Layout.js
with the content:
import { h } from "hyperapp";
const Layout = (props, page) => h("div",{class:"container"}, [
h("article", {}, page),
])
export default Layout
Now, lets update our src/index.js
to;
import { h, app } from "hyperapp";
import { Route, location } from "@hyperapp/router";
import Layout from "./components/Layout.js";
import Home from "./pages/Home.js";
import About from "./pages/About.js";
const state = {
location: location.state
};
const actions = {
location: location.actions
};
const view = () => h("div", {class:"main"}, [
h(Route, { path: "/", render: () => Layout({}, Home) }),
h(Route, { path: "/about", render: () => Layout({}, About) })
])
const main = logger()(app)(state, actions, view, document.body)
const unsubscribe = location.subscribe(main.location);
Before we go any further, lets just build the project and see what we have got working here. Run parcel
in your terminal and fire up localhost:1234
The route should be working. If you type in localhost:1234
you will see the src/components/Layout.js
being rendered with the tags from the src/pages/Home.js
If you type in localhost:1234/about
you will see the text “About” from the src/pages/About.js
being rendered. We have a working router switching between 2 pages.
Lets look at the code again to better understand the flow. In src/index.js
we have the block;
const view = () => h("div", {class:"main"}, [
h(Route, { path: "/", render: () => Layout({}, Home) }),
h(Route, { path: "/about", render: () => Layout({}, About) })
])
When the “/” route is called, Hyperapp renders the Layout({}, Home)
function. Home here has been pulled in as an import `import Home from "./pages/Home.js";
Layout here at the end of the day, is just a function which takes in Home
as an argument. In src/components/Layout.js
we have the block;
const Layout = (props, page) => h("div",{class:"container"}, [
h("article", {}, page),
])
In the case of the “/” route, Layout gets Home
as the page
argument and renders it.
Now, we will add in a Navbar at the top of the app to making navigating between the pages easy.
Add a new file src/components/Navbar.js
with the content:
import { h } from "hyperapp";
import { Link } from "@hyperapp/router";
const Navbar = () => h("nav", {}, [
h(Link, {"to": "/" }, "Home"),
h(Link, {"to": "/about" }, "About")
])
export default Navbar
It will render a simple <nav>
element with links to our two supported routes.
Link
is a custom element provided by the router and enables us to route pages on the client side without refreshing the page.
Finally, lets update the Layout and add our new Navbar component in there.
import { h } from "hyperapp";
import Navbar from './Navbar.js'
const Layout = (props, page) => h("div",{class:"container"}, [
h(Navbar),
h("article", {}, page),
])
export default Layout
Hit save. run parcel
and open localhost:1234
Congratulations. We now have a barebones webapp with multiple pages and working router in place. Its a good platform to build upon.
The code so far can be found here