feat: add custom 404 page and update nginx error handling
This commit is contained in:
84
app/not-found.tsx
Normal file
84
app/not-found.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { motion } from 'framer-motion';
|
||||
import AnimatedBackground from '@/components/AnimatedBackground';
|
||||
import Footer from '@/components/Footer';
|
||||
import Logo from '@/components/Logo';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Home } from 'lucide-react';
|
||||
|
||||
export default function NotFound() {
|
||||
React.useEffect(() => {
|
||||
// Force dark mode on html element for the 404 page
|
||||
document.documentElement.classList.remove('light');
|
||||
document.documentElement.classList.add('dark');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<main className="relative min-h-screen dark text-foreground flex flex-col">
|
||||
<AnimatedBackground />
|
||||
|
||||
<div className="flex-1 flex flex-col items-center justify-center px-4 py-20 relative z-10">
|
||||
<div className="max-w-6xl mx-auto text-center">
|
||||
{/* Logo */}
|
||||
<motion.div
|
||||
className="mb-8 flex justify-center"
|
||||
initial={{ opacity: 0, y: -50 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
>
|
||||
<Logo size={100} />
|
||||
</motion.div>
|
||||
|
||||
{/* 404 heading */}
|
||||
<motion.h1
|
||||
className="text-7xl md:text-9xl font-bold mb-6 bg-clip-text text-transparent bg-gradient-to-r from-purple-400 via-pink-400 to-cyan-400"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
>
|
||||
404
|
||||
</motion.h1>
|
||||
|
||||
{/* Subtitle */}
|
||||
<motion.p
|
||||
className="text-xl md:text-3xl font-medium mb-4"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
>
|
||||
Page Not Found
|
||||
</motion.p>
|
||||
|
||||
{/* Description */}
|
||||
<motion.p
|
||||
className="text-base md:text-lg text-muted-foreground/80 mb-12 max-w-md mx-auto"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.6 }}
|
||||
>
|
||||
The tool or page you are looking for doesn't exist or has been moved.
|
||||
</motion.p>
|
||||
|
||||
{/* CTA Button */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.8 }}
|
||||
>
|
||||
<Link href="/">
|
||||
<Button size="lg" className="rounded-full px-8 h-14 text-lg font-semibold bg-gradient-to-r from-purple-500 to-cyan-500 hover:from-purple-600 hover:to-cyan-600 border-none transition-all duration-300">
|
||||
<Home className="mr-2 h-5 w-5" />
|
||||
Back to Home
|
||||
</Button>
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -30,6 +30,11 @@ http {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
error_page 404 /404.html;
|
||||
location = /404.html {
|
||||
internal;
|
||||
}
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
|
||||
Reference in New Issue
Block a user