diff --git a/app/about/page.tsx b/app/about/page.tsx
index 128f340..52e8fd2 100644
--- a/app/about/page.tsx
+++ b/app/about/page.tsx
@@ -1,5 +1,19 @@
import { AboutContent } from "@/components/about-content";
+import { PersonJsonLd } from "@/components/json-ld";
export default function AboutPage() {
- return ;
+ return (
+ <>
+
+
+ >
+ );
}
diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx
index c2a1e95..4b48efb 100644
--- a/app/blog/[slug]/page.tsx
+++ b/app/blog/[slug]/page.tsx
@@ -1,7 +1,10 @@
import { notFound } from "next/navigation";
import { BlogDetailContent } from "@/components/blog-detail-content";
+import { ArticleJsonLd } from "@/components/json-ld";
import { getBlogDetailBySlug } from "@/data/blog-detail";
+const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://poyrazavsever.com";
+
type BlogDetailPageProps = {
params: Promise<{ slug: string }>;
};
@@ -14,5 +17,17 @@ export default async function BlogDetailPage({ params }: BlogDetailPageProps) {
notFound();
}
- return ;
+ return (
+ <>
+
+
+ >
+ );
}
diff --git a/app/layout.tsx b/app/layout.tsx
index 8699f75..ce1c870 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,7 +1,8 @@
-import type { Metadata } from "next";
+import type { Metadata } from "next";
import "./globals.css";
import { AppShell } from "@/components/app-shell";
+import { GoogleAnalytics } from "@/components/google-analytics";
export const metadata: Metadata = {
metadataBase: new URL("https://poyrazavsever.com"),
@@ -85,6 +86,7 @@ export default function RootLayout({
return (
+
{children}
diff --git a/app/robots.ts b/app/robots.ts
new file mode 100644
index 0000000..6825975
--- /dev/null
+++ b/app/robots.ts
@@ -0,0 +1,16 @@
+import type { MetadataRoute } from "next";
+
+const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://poyrazavsever.com";
+
+export default function robots(): MetadataRoute.Robots {
+ return {
+ rules: [
+ {
+ userAgent: "*",
+ allow: "/",
+ disallow: ["/api/", "/_next/"],
+ },
+ ],
+ sitemap: `${SITE_URL}/sitemap.xml`,
+ };
+}
diff --git a/app/sitemap.ts b/app/sitemap.ts
new file mode 100644
index 0000000..150a874
--- /dev/null
+++ b/app/sitemap.ts
@@ -0,0 +1,30 @@
+import { listBlogDetails } from "@/data/blog-detail";
+import type { MetadataRoute } from "next";
+
+const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://poyrazavsever.com";
+
+export default async function sitemap(): Promise {
+ const posts = await listBlogDetails();
+
+ const staticRoutes: MetadataRoute.Sitemap = [
+ { url: SITE_URL, lastModified: new Date(), changeFrequency: "weekly", priority: 1.0 },
+ { url: `${SITE_URL}/about`, lastModified: new Date(), changeFrequency: "monthly", priority: 0.8 },
+ { url: `${SITE_URL}/about/references`, lastModified: new Date(), changeFrequency: "monthly", priority: 0.5 },
+ { url: `${SITE_URL}/about/volunteer-community`, lastModified: new Date(), changeFrequency: "monthly", priority: 0.5 },
+ { url: `${SITE_URL}/blog`, lastModified: new Date(), changeFrequency: "weekly", priority: 0.9 },
+ { url: `${SITE_URL}/projects`, lastModified: new Date(), changeFrequency: "monthly", priority: 0.8 },
+ { url: `${SITE_URL}/content`, lastModified: new Date(), changeFrequency: "weekly", priority: 0.7 },
+ { url: `${SITE_URL}/contact`, lastModified: new Date(), changeFrequency: "yearly", priority: 0.5 },
+ { url: `${SITE_URL}/links`, lastModified: new Date(), changeFrequency: "monthly", priority: 0.4 },
+ { url: `${SITE_URL}/snippets`, lastModified: new Date(), changeFrequency: "weekly", priority: 0.7 },
+ ];
+
+ const blogRoutes: MetadataRoute.Sitemap = posts.map((post) => ({
+ url: `${SITE_URL}/blog/${post.slug}`,
+ lastModified: post.date ? new Date(post.date) : new Date(),
+ changeFrequency: "monthly",
+ priority: 0.7,
+ }));
+
+ return [...staticRoutes, ...blogRoutes];
+}
diff --git a/components/json-ld.tsx b/components/json-ld.tsx
new file mode 100644
index 0000000..89bc244
--- /dev/null
+++ b/components/json-ld.tsx
@@ -0,0 +1,82 @@
+const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://poyrazavsever.com";
+
+export type PersonJsonLdProps = {
+ name: string;
+ url?: string;
+ image?: string;
+ jobTitle?: string;
+ sameAs?: string[];
+};
+
+export function PersonJsonLd({
+ name,
+ url = SITE_URL,
+ image = `${SITE_URL}/logo/logo.jpeg`,
+ jobTitle = "Fullstack Developer",
+ sameAs = [],
+}: PersonJsonLdProps) {
+ const data = {
+ "@context": "https://schema.org",
+ "@type": "Person",
+ name,
+ url,
+ image,
+ jobTitle,
+ sameAs,
+ };
+
+ return (
+
+ );
+}
+
+export type ArticleJsonLdProps = {
+ title: string;
+ description: string;
+ url: string;
+ image: string;
+ datePublished: string;
+ authorName?: string;
+};
+
+export function ArticleJsonLd({
+ title,
+ description,
+ url,
+ image,
+ datePublished,
+ authorName = "Poyraz Avsever",
+}: ArticleJsonLdProps) {
+ const data = {
+ "@context": "https://schema.org",
+ "@type": "Article",
+ headline: title,
+ description,
+ url,
+ image: image.startsWith("http") ? image : `${SITE_URL}${image}`,
+ datePublished,
+ author: {
+ "@type": "Person",
+ name: authorName,
+ url: SITE_URL,
+ },
+ publisher: {
+ "@type": "Person",
+ name: authorName,
+ logo: {
+ "@type": "ImageObject",
+ url: `${SITE_URL}/logo/logo.jpeg`,
+ },
+ },
+ };
+
+ return (
+
+ );
+}