Custom 404 Page
Replace the default 404 response with a custom HTML page, branded layout, or application-specific fallback content.
The router package allows applications to replace the default 404 page not found response with a custom handler.
Custom 404 pages are useful for:
- branded error pages
- frontend applications
- marketing websites
- SPA fallbacks
- custom error templates
- localized error messages
Registering a Custom 404 Handler
Use r.NotFound(...) to register a custom handler.
r.NotFound(func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("Custom 404 Page"))
})This handler is triggered whenever no route matches the incoming request.
Example
Example project structure:
custom_error_page/
├── public/
│ ├── favicon.ico
│ └── style.css
├── templates/
│ └── 404.html
└── main.goExample application:
package main
import (
"log/slog"
"net/http"
"os"
"github.com/netlifeguru/router"
)
func main() {
r := router.New()
r.Static("/assets/", "./public")
r.NotFound(func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
w.Header().Set("Content-Type", "text/html")
htmlContent, err := os.ReadFile("./templates/404.html")
if err != nil {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("404 - Page Not Found"))
return
}
w.WriteHeader(http.StatusNotFound)
w.Write(htmlContent)
})
r.GET("/", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
w.Header().Set("Content-Type", "text/html")
w.Write([]byte(`
<h1>Welcome to netlife.guru</h1>
<p>Try visiting a non-existent URL to see the custom 404 page.</p>
`))
})
if err := r.ListenAndServe(":8000"); err != nil {
slog.Error("failed to start server", "error", err)
os.Exit(1)
}
}Run the application:
go run .Then open a non-existing route:
http://localhost:8000/unknown-pageThe router automatically renders the custom 404.html template.
Template Example
Example minimal template:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404 - Page Not Found</title>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
<h1>404 - Page Not Found</h1>
<p>The requested page does not exist.</p>
<a href="/">Back to homepage</a>
</body>
</html>The example above loads static assets from:
/assets/using the router static file system:
r.Static("/assets/", "./public")Fallback Handling
If the template file cannot be loaded:
os.ReadFile("./templates/404.html")the handler can safely fall back to a simpler response.
Example:
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("404 - Page Not Found"))This prevents broken templates from causing application errors.
Notes
The custom 404 handler is a normal route handler and can use:
- templates
- database queries
- localization
- sessions
- middleware context
- static assets
This makes it possible to build fully customized application-specific error pages.
Custom 404 Handler
Override the default 404 response with a custom handler for inline HTML, localized messages, JSON responses, or lightweight fallback pages.
Error Handling
Handle startup errors, runtime failures, and panic logging using structured slog-compatible logging with automatic JSON file output.