feat(seo): implement SEO audit remediations

- Add dynamic sitemap.ts, robots.ts, and llms.txt route
- Add metadataBase and JSON-LD Organization schema to layout
- Set canonical alternates for all routes
- Migrate raw img tags to next/image for LCP optimization
- Add SEO dictionary strings to tr.json and en.json
This commit is contained in:
mstfyldz
2026-06-04 12:29:19 +03:00
parent 4996ec38e6
commit e1d8bae5a4
17 changed files with 233 additions and 28 deletions
+8 -4
View File
@@ -1,6 +1,7 @@
"use client";
import { useState } from "react";
import Image from "next/image";
import { motion, AnimatePresence } from "framer-motion";
import { X, ZoomIn } from "lucide-react";
import { Badge } from "@/app/components/ui/badge";
@@ -75,10 +76,11 @@ export default function GaleriClient({ lang, dict }: { lang: string; dict: any }
className="group relative aspect-square cursor-pointer overflow-hidden"
onClick={() => setLightbox(img)}
>
<img
<Image
src={img.src}
alt={img.title}
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
fill
className="object-cover transition-transform duration-700 group-hover:scale-110"
/>
<div className="absolute inset-0 bg-[var(--color-moy-dark)]/0 group-hover:bg-[var(--color-moy-dark)]/50 transition-all duration-300 flex flex-col items-center justify-center gap-3">
<ZoomIn
@@ -125,10 +127,12 @@ export default function GaleriClient({ lang, dict }: { lang: string; dict: any }
className="max-w-4xl w-full"
onClick={(e) => e.stopPropagation()}
>
<img
<Image
src={lightbox.src}
alt={lightbox.title}
className="w-full max-h-[80vh] object-contain"
width={1200}
height={800}
className="w-full h-auto max-h-[80vh] object-contain"
/>
<p className="text-center text-white font-serif text-xl mt-4">{lightbox.title}</p>
</motion.div>
+11 -3
View File
@@ -1,9 +1,17 @@
import { getDictionary, Locale } from "../../dictionaries";
import GaleriClient from "./GaleriClient";
export const metadata = {
title: "Galeri | Moy Group",
};
export async function generateMetadata({ params }: { params: Promise<{ lang: string }> }) {
const { lang } = await params;
const dict = await getDictionary(lang as Locale);
return {
title: dict.seo.gallery.title,
description: dict.seo.gallery.description,
alternates: {
canonical: `/${lang}/galeri`,
},
};
}
export default async function GaleriPage({
params,