Change from pat router to ServeMux

Hugo is a static site generator build with Go. With Hugo you create Markdown
files for your content and the HTML will be generated automatically.

One reason for a non-static setup is the option to have contact forms without the
need to expose your email. A simple way for people to send messages without
needing them to write an email.

You probably know Formspree or a similar service. They offer you the
possibility to just use a standard HTML form on your page and they handle the
messages and send them to you via mail, so you don’t need to manage a database
and all that stuff yourself.

I will build a very simple contact form in Go, but for self-hosting. The idea is that the API should be outside from my hugo projects. I have more than one Project which need a contact form.

I have set up a public repo for all that

Here is a code snipped. As router I use pat. I think it would be better to use
ServeMux from the public library.

Please take a look to the repo and I need help to change from pat to ServeMux.

package main

import (

func main() {
	mux := pat.New()
	mux.Get("/", http.HandlerFunc(index))
	mux.Post("/", http.HandlerFunc(send))
	mux.Get("/confirmation", http.HandlerFunc(confirmation))

	log.Println("Listening on port 8080")
	http.ListenAndServe(":8080", mux)

func index(w http.ResponseWriter, r *http.Request) {
	render(w, "templates/index.html", nil)

func send(w http.ResponseWriter, r *http.Request) {
	msg := &Message{
		Name:    r.FormValue("name"),
		Email:   r.FormValue("email"),
		Subject: r.FormValue("subject"),
		Content: r.FormValue("content"),

	if msg.Validate() == false {
		render(w, "templates/index.html", msg)

	if err := msg.Deliver(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)

	http.Redirect(w, r, "/confirmation", http.StatusSeeOther)

func confirmation(w http.ResponseWriter, r *http.Request) {
	render(w, "templates/confirmation.html", nil)

func render(w http.ResponseWriter, filename string, data interface{}) {
	tmpl, err := template.ParseFiles(filename)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	if err := tmpl.Execute(w, data); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.