Warm Up

This first exercise is just a warm up to get you familiar with the application we're building for today. The key things you need to understand from this exercise are:
  1. The public/index.html is what we want loaded for browser document requests to our application.
  2. The application is served by a hono.js server that serves the static assets and the API endpoint.
This is not an node/hono.js workshop, so we'll be really hand-holdy on things to avoid you wasting time acquiring knowledge of things that you didn't come here to learn.
That said, because we're not using any build tools, there may be some things we're doing you may not be familiar with.

Import Map

Because we're not using any tools to bundle imports, we're using native EcmaScript Modules (ESM). Our code is written to run in two environments in this project:
  • Node.js
  • Browsers
In Node.js, there is a module resolution algorithm that is used to resolve modules. In the browser, there is no such algorithm. To make our code work in both environments, we're using an importmap to map the module names to the actual URLs where the modules can be found.
Here's an example of an importmap script:
<script type="importmap">
	{
		"imports": {
			"react": "https://esm.sh/react",
			"react-dom": "https://esm.sh/react-dom",
			"react-dom/client": "https://esm.sh/react-dom/client"
		}
	}
</script>
<script type="module" src="/ui/index.js"></script>
// the importmap above will allow the browser to know where to go to get the
// modules when they are imported.
import { createElement as h } from 'react'
import { renderRoot } from 'react-dom/client'

// because this file was loaded from /ui/index.js, the browser will know to
// import this file from /ui/app.js
import { App } from './app.js'

// other stuff here...
You'll notice we're using esm.sh to load the modules. This is a service that provides ESM versions of popular libraries. It bundles them on-demand and serves them. This works nicely for our build-less setup (thought it does mean you need to be connected to the internet to work through this workshop).

Hono.js static

As mentioned, this is not a workshop about hono.js, but we're using it to serve our static assets and API endpoints. Here's how serving static assets works with hono.js:
import { serveStatic } from '@hono/node-server/serve-static'
import { Hono } from 'hono'

const app = new Hono({ strict: true })

// this line tells hono.js to serve the files in the public directory when a
// request is made to the root of the server.
app.use('/*', serveStatic({ root: './public' }))

Hono.js Route Patterns

Hono.js has a special format for defining routes that can be used to match patterns in the URL. Here's an example of a route pattern:
app.get('/api/:id?', (req, res) => {
	res.json({ id: req.params.id })
})
In this example, the :id? is a pattern that will match any URL that starts with /api/ and has an optional id parameter. The req.params.id will be populated with the value of the id parameter in the URL.