fix: SEO canonical URLs, LCP performance, remove unused dependencies
All checks were successful
CI / CD / test-build (push) Successful in 10m16s
CI / CD / deploy-dev (push) Successful in 1m55s
CI / CD / deploy-production (push) Has been skipped

- Remove duplicate app/projects/ route (was causing 5xx and soft 404)
- Fix nginx: redirect www.dk0.dev → dk0.dev (non-www canonical)
- Fix not-found.tsx: locale-prefixed links, remove framer-motion dependency
- Add fetchPriority='high' and will-change to Hero LCP image
- Add preconnect hints for hardcover.app and cms.dk0.dev
- Reduce background blur from 100px to 80px (LCP rendering delay)
- Remove boneyard-js (~20 KiB), replace with custom Skeleton component
- Remove react-icons (~10 KiB), replace with inline SVGs
- Conditionally render mobile menu (saves ~20 DOM nodes)
- Add /books to sitemap
- Optimize image config with explicit deviceSizes/imageSizes
This commit is contained in:
2026-04-17 09:50:31 +02:00
parent dd46bcddc7
commit 2c2c1f5d2d
22 changed files with 144 additions and 737 deletions

View File

@@ -6,7 +6,7 @@ import { ArrowUpRight } from "lucide-react";
import Link from "next/link";
import Image from "next/image";
import { useLocale, useTranslations } from "next-intl";
import { Skeleton } from "boneyard-js/react";
import { Skeleton } from "./ui/Skeleton";
import ProjectThumbnail from "./ProjectThumbnail";
interface Project {
@@ -64,9 +64,19 @@ const Projects = () => {
</Link>
</div>
<Skeleton name="projects-grid" loading={loading} animate="shimmer" transition>
{loading ? (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-12">
{Array.from({ length: 4 }).map((_, i) => (
<div key={i} className="space-y-4">
<Skeleton className="aspect-[16/10] sm:aspect-[4/3] rounded-2xl sm:rounded-3xl" />
<Skeleton className="h-6 w-3/4" />
<Skeleton className="h-4 w-1/2" />
</div>
))}
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-12">
{projects.length === 0 && !loading ? (
{projects.length === 0 ? (
<div className="col-span-2 py-12 text-center text-stone-400 dark:text-stone-600 text-sm">
{t("noProjects")}
</div>
@@ -121,7 +131,7 @@ const Projects = () => {
</motion.div>
)))}
</div>
</Skeleton>
)}
</div>
</section>
);