feat: SEO altyapısı + admin editör/favicon/menü düzeltmeleri

Admin & site:
- @tailwindcss/typography ekle → editör ve yayın içeriği prose stilleriyle düzgün render
- Favicon: logo.png'den kare app/icon.png + apple-icon.png, varsayılan favicon.ico kaldırıldı
- SEO keyword: seo_settings.default_keywords + seo_pages.keywords + buildMetadata birleştirme
- Menü düzeni admin'den yönetilebilir (site_settings.nav_items, /admin/menu, header & mobile-menu refactor)

SEO:
- app/sitemap.ts (statik + blog/hizmet/çözüm/proje/sektör dinamik)
- app/robots.ts (sitemap ref + /admin,/api disallow)
- app/llms.txt/route.ts (AI/LLM rehberi)
- BlogPosting/Service/FAQ/Article JSON-LD wire (json-ld bileşenleri bağlandı)
- buildMetadata: blog/proje OG görseli + type article + keywords birleştirme düzeltmesi
- blog tags → keyword
This commit is contained in:
egecankomur
2026-06-04 07:15:18 +03:00
parent a321ac5c9b
commit d49c9aa225
26 changed files with 780 additions and 151 deletions
+3
View File
@@ -6,6 +6,7 @@ import { ArrowLeft, Calendar } from "lucide-react";
import { renderContent } from "@/lib/content-render";
import { getPostBySlug } from "@/lib/data";
import { buildMetadata } from "@/lib/seo";
import { BlogPostingLd } from "@/components/json-ld";
import { ContentSidebar } from "@/components/content-sidebar";
export async function generateMetadata({
@@ -19,6 +20,7 @@ export async function generateMetadata({
return buildMetadata(`/blog/${slug}`, {
title: post.seo_title || post.title,
description: post.seo_description || post.excerpt || undefined,
keywords: post.tags ?? undefined,
openGraph: {
title: post.seo_title || post.title,
description: post.seo_description || post.excerpt || undefined,
@@ -44,6 +46,7 @@ export default async function BlogPostPage({
return (
<div className="mx-auto max-w-7xl px-6 py-16">
<BlogPostingLd post={post} />
<Link
href="/blog"
className="inline-flex items-center gap-1 text-sm text-[var(--muted)] hover:text-[var(--navy)]"
+3
View File
@@ -9,6 +9,7 @@ import { SectionTitle } from "@/components/section-title";
import { FaqList } from "@/components/faq-list";
import { ServiceHero } from "@/components/service-hero";
import { ServiceSidebar } from "@/components/service-sidebar";
import { ServiceLd, FaqLd } from "@/components/json-ld";
import type { FaqItem } from "@/lib/types";
export async function generateMetadata({
@@ -59,6 +60,8 @@ export default async function ServiceDetailPage({
return (
<>
<ServiceLd service={service} settings={settings} />
<FaqLd items={faqItems} />
<ServiceHero service={service} settings={settings} />
<div className="mx-auto grid max-w-7xl gap-12 px-6 py-16 lg:grid-cols-[1.5fr_1fr]">
+2
View File
@@ -7,6 +7,7 @@ import { renderContent } from "@/lib/content-render";
import { getProjectBySlug, listProjects } from "@/lib/data";
import { buildMetadata } from "@/lib/seo";
import { Gallery } from "@/components/gallery";
import { ArticleLd } from "@/components/json-ld";
import { TrendingUp } from "lucide-react";
import type { ProjectMetric } from "@/lib/types";
@@ -74,6 +75,7 @@ export default async function ProjectDetailPage({
return (
<>
<ArticleLd post={project} />
<section className="border-b border-[var(--border)]">
<div className="mx-auto max-w-7xl px-6 py-12">
<Link