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-linkExpected 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.