Files
Epicnabbo-Catalogus-Updated…/src/app/not-found.tsx
T
Simo 6f15e0c8a3 Production hardening: error pages, rate limiting, metadata
- Custom not-found (404) + error / global-error boundaries, styled with
  the public design system; raw errors logged, never shown to users.
- In-process rate limiter (src/lib/rate-limit.ts) wired into the abuse-
  prone flows: login (10/5min/IP), register (5/10min/IP), password-reset
  request (3/15min/IP), keyed by the proxy-forwarded client IP.
- SEO/metadata: root generateMetadata sets a `%s · {hotel}` title
  template from the live hotel_name; dynamic generateMetadata on
  news/[slug] (article title + excerpt) and u/[username] (name + motto);
  static titles on 12 primary public pages.
- env.ts: added the vars introduced since (PASSWORD_HASH, OPENAI_API_KEY,
  DISCORD_WEBHOOK_URL, ALERT_EMAIL, PAYPAL_*) so env stays authoritative.

Verified on the prod server: /missing → 404 card, news title renders
"News · Habbo". tsc 0, vitest 49/49, next build 0.
2026-06-28 20:12:12 +02:00

23 lines
725 B
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Link from "next/link";
import { ContentCard } from "@/components/public/ui";
export default function NotFound() {
return (
<main style={{ display: "grid", gap: "1.5rem" }}>
<ContentCard icon="🧭" title="Page not found" subtitle="Error 404">
<p className="muted" style={{ marginTop: 0 }}>
The page you’re looking for doesn’t exist or has moved.
</p>
<div style={{ display: "flex", gap: "0.6rem", flexWrap: "wrap" }}>
<Link className="btn btn-primary" href="/">
Back home
</Link>
<Link className="btn btn-outline" href="/news">
Latest news
</Link>
</div>
</ContentCard>
</main>
);
}