routes.mdin: /docs/cmd/demo-server/

import (




Becuase we're going to be doing lots of composition of request handers and http handlers (from veun), we have some helpers defined.

These two are to wrap a request.Handler(Func) and create an http.Handler.

var (
	h  = vhttp.Handler
	hf = vhttp.HandlerFunc


This is a wrapper for our html page, with default title, css, and js files provided. page.Handler returns a middleware-y function.

var html = page.Handler(page.Data{
	Title:    "veun-http-demo", // default title
	CSSFiles: []string{"/static/styles.css"},
	JSFiles:  []string{"/static/htmx.1.9.9.min.js", "/static/prism.js"},

Any view/request.Handler can mutate the data we pass here by implementing the page.DataMutator interface.


Open our function body:

func routes() http.Handler {
    mux := http.NewServeMux()

Docs & Components

Docs are really the only interesting route here. It serves everything, from the static documents to demo compontents in the internal/components path.

mux.Handle("/docs/", h(html(docsHandler)))

Pages for lazy loading

mux.Handle("/e/text", h(request.Always(
        el.P{el.Em{el.Text("text output,")}},
        el.P{el.Text("and more of it")},

Example not-found route:

mux.Handle("/e/not_found", h(request.Always(notFoundView)))


handler.OnlyRoot is in the veun library that ensures that when we're mounting at the / path, we 404 if it's anything other than that exact path.

mux.Handle("/", handler.OnlyRoot(h(html(index))))

Closing out the server

There is another built in handler handler.Checked which will continue trying http.Handlers if it hits a 404 and return the last one.

This way, we can implement a pretty nice static file serving fallback for when any routes aren't actually defined, and even add our own 404 handler, it's pretty neat.

return handler.Checked(
	mux,                      // the ServeMux we've just been adding routes to
	staticFileServer(),       // falls back to the static file server if we 404
	h(html(notFoundHandler)), // our own custom notFoundHandler

Closing server: