NetLife Guru

Open source Go packages for fast, maintainable web systems. Built with a documentation-first approach.

Product
OverviewGolang packagesNews
Documentation
DocumentationGo LoggerGo RouterGo DB Form
Company
OverviewContactNewsGitHub
Community / Support
Supportinfo@netlife.guru
© 2026 NetLife Guru. All rights reserved.
GitHubinfo@netlife.guru
NetLife GuruNetLife GuruNetLife Guru
NetLife GuruNetLife GuruNetLife Guru
OverviewDocumentationNewsSupportContact

Golang packages

About
LoggingHealth ChecksProfilingMulti-Server SupportStatic FilesRate LimitingPanic RecoveryCustom 404 HandlerCustom 404 PageError Handling
RouterFeatures

Custom 404 Handler

Override the default 404 response with a custom handler for inline HTML, localized messages, JSON responses, or lightweight fallback pages.

The router package allows applications to replace the default 404 page not found response with a custom handler.

This is useful for:

  • custom inline HTML responses
  • JSON API error responses
  • localized messages
  • lightweight fallback pages
  • frontend routing fallbacks
  • application-specific error handling

Registering a Custom Handler

Use r.NotFound(...) to override the default 404 behavior.

r.NotFound(func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
	w.WriteHeader(http.StatusNotFound)
	w.Write([]byte("Custom 404"))
})

The handler is executed whenever no matching route exists.


Example

package main

import (
	"log/slog"
	"net/http"
	"os"

	"github.com/netlifeguru/router"
)

func main() {
	r := router.New()

	r.NotFound(func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		w.Header().Set("Content-Type", "text/html")

		w.WriteHeader(http.StatusNotFound)

		w.Write([]byte(`
			<h1>404</h1>
			<p>The page you are looking for does not exist.</p>
		`))
	})

	r.GET("/", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		w.Header().Set("Content-Type", "text/html")

		w.Write([]byte(`
			Hello World!
			<br>
			<a href="/any-broken-link">
				Click here to trigger the 404 handler
			</a>
		`))
	})

	if err := r.ListenAndServe(":8000"); err != nil {
		slog.Error("failed to start server", "error", err)
		os.Exit(1)
	}
}

Run the application:

go run .

Open:

http://localhost:8000/any-broken-link

Expected response:

<h1>404</h1>
<p>The page you are looking for does not exist.</p>

Returning JSON Responses

The custom handler can also return JSON responses for APIs.

Example:

r.NotFound(func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusNotFound)

	w.Write([]byte(`{
		"error": "route_not_found"
	}`))
})

This is useful for REST APIs and frontend applications expecting structured responses.


Inline vs Template-Based Pages

Simple inline responses are useful for lightweight applications:

w.Write([]byte("<h1>404</h1>"))

For larger applications, template-based pages are usually preferred.

See the dedicated Custom 404 Page guide for serving full HTML templates, static assets, and branded error pages.


Notes

The custom 404 handler is a standard route handler and can access:

  • request context
  • middleware data
  • sessions
  • templates
  • database connections
  • localization systems

This makes it possible to fully customize how missing routes are handled across the application.

Panic Recovery

Handle panics from route handlers safely using a custom recovery handler and fail-safe internal recovery.

Custom 404 Page

Replace the default 404 response with a custom HTML page, branded layout, or application-specific fallback content.

On this page

Registering a Custom HandlerExampleReturning JSON ResponsesInline vs Template-Based PagesNotes