feat(seo): add localized route metadata
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
import { AboutContent } from "@/components/about-content";
|
||||
import { PersonJsonLd } from "@/components/json-ld";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({ locale, page: "about", path: "/about" });
|
||||
}
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
import { ReferencesDetailContent } from "@/components/references-detail-content";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({
|
||||
locale,
|
||||
page: "references",
|
||||
path: "/about/references",
|
||||
});
|
||||
}
|
||||
|
||||
export default function AboutReferencesPage() {
|
||||
return <ReferencesDetailContent />;
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
import { VolunteerCommunityContent } from "@/components/volunteer-community-content";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({
|
||||
locale,
|
||||
page: "volunteerCommunity",
|
||||
path: "/about/volunteer-community",
|
||||
});
|
||||
}
|
||||
|
||||
export default function AboutVolunteerCommunityPage() {
|
||||
return <VolunteerCommunityContent />;
|
||||
|
||||
@@ -2,10 +2,13 @@ import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import { BlogDetailContent } from "@/components/blog-detail-content";
|
||||
import { ArticleJsonLd } from "@/components/json-ld";
|
||||
import { getBlogDetailBySlug } from "@/data/blog-detail";
|
||||
import { getBlogDetailBySlug, getBlogTranslations } from "@/data/blog-detail";
|
||||
import { isNewsletterCategory } from "@/data/blog";
|
||||
|
||||
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://poyrazavsever.com";
|
||||
import {
|
||||
createAlternates,
|
||||
getLocalizedUrl,
|
||||
type SiteLocale,
|
||||
} from "@/lib/seo";
|
||||
|
||||
type AgendaDetailPageProps = {
|
||||
params: Promise<{ locale: string; slug: string }>;
|
||||
@@ -21,17 +24,30 @@ export async function generateMetadata({
|
||||
return { title: locale === "en" ? "Agenda post not found" : "Gündem yazısı bulunamadı" };
|
||||
}
|
||||
|
||||
const url = `${SITE_URL}${locale === "en" ? "/en" : ""}/agenda/${post.slug}`;
|
||||
const siteLocale = locale as SiteLocale;
|
||||
const translations = await getBlogTranslations(post);
|
||||
const paths = Object.fromEntries(
|
||||
translations.map((translation) => [
|
||||
translation.lang,
|
||||
`/agenda/${translation.slug}`,
|
||||
]),
|
||||
);
|
||||
const url = getLocalizedUrl(siteLocale, `/agenda/${post.slug}`);
|
||||
|
||||
return {
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
alternates: { canonical: url },
|
||||
alternates: createAlternates(siteLocale, paths),
|
||||
openGraph: {
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
url,
|
||||
type: "article",
|
||||
locale: locale === "en" ? "en_US" : "tr_TR",
|
||||
alternateLocale:
|
||||
translations.length > 1
|
||||
? [locale === "en" ? "tr_TR" : "en_US"]
|
||||
: undefined,
|
||||
publishedTime: post.date,
|
||||
authors: [post.author],
|
||||
images: [
|
||||
@@ -60,7 +76,10 @@ export default async function AgendaDetailPage({ params }: AgendaDetailPageProps
|
||||
notFound();
|
||||
}
|
||||
|
||||
const url = `${SITE_URL}${locale === "en" ? "/en" : ""}/agenda/${post.slug}`;
|
||||
const url = getLocalizedUrl(
|
||||
locale as SiteLocale,
|
||||
`/agenda/${post.slug}`,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { BlogContent } from "@/components/blog-content";
|
||||
import { getAgendaPageData } from "@/data/blog";
|
||||
import { createPageMetadata } from "@/lib/seo";
|
||||
|
||||
type AgendaPageProps = {
|
||||
params: Promise<{ locale: string }>;
|
||||
@@ -15,10 +16,12 @@ export async function generateMetadata({ params }: AgendaPageProps): Promise<Met
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations({ locale, namespace: "Agenda" });
|
||||
|
||||
return {
|
||||
return createPageMetadata({
|
||||
locale: locale === "en" ? "en" : "tr",
|
||||
title: t("title"),
|
||||
description: t("description"),
|
||||
};
|
||||
path: "/agenda",
|
||||
});
|
||||
}
|
||||
|
||||
export default async function AgendaPage({ params, searchParams }: AgendaPageProps) {
|
||||
|
||||
@@ -52,6 +52,7 @@ export async function generateMetadata({
|
||||
languages: {
|
||||
"tr-TR": turkishUrl,
|
||||
"en-US": englishUrl,
|
||||
"x-default": turkishUrl,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
|
||||
@@ -32,6 +32,7 @@ export async function generateMetadata({
|
||||
languages: {
|
||||
"tr-TR": `${SITE_URL}/animation-sources`,
|
||||
"en-US": `${SITE_URL}/en/animation-sources`,
|
||||
"x-default": `${SITE_URL}/animation-sources`,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
|
||||
@@ -2,10 +2,13 @@ import { notFound, permanentRedirect } from "next/navigation";
|
||||
import { Metadata } from "next";
|
||||
import { BlogDetailContent } from "@/components/blog-detail-content";
|
||||
import { ArticleJsonLd } from "@/components/json-ld";
|
||||
import { getBlogDetailBySlug } from "@/data/blog-detail";
|
||||
import { getBlogDetailBySlug, getBlogTranslations } from "@/data/blog-detail";
|
||||
import { isNewsletterCategory } from "@/data/blog";
|
||||
|
||||
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://poyrazavsever.com";
|
||||
import {
|
||||
createAlternates,
|
||||
getLocalizedUrl,
|
||||
type SiteLocale,
|
||||
} from "@/lib/seo";
|
||||
|
||||
type BlogDetailPageProps = {
|
||||
params: Promise<{ locale: string; slug: string }>;
|
||||
@@ -21,16 +24,30 @@ export async function generateMetadata({ params }: BlogDetailPageProps): Promise
|
||||
};
|
||||
}
|
||||
|
||||
const url = `${SITE_URL}/blog/${post.slug}`;
|
||||
const siteLocale = locale as SiteLocale;
|
||||
const translations = await getBlogTranslations(post);
|
||||
const paths = Object.fromEntries(
|
||||
translations.map((translation) => [
|
||||
translation.lang,
|
||||
`/blog/${translation.slug}`,
|
||||
]),
|
||||
);
|
||||
const url = getLocalizedUrl(siteLocale, `/blog/${post.slug}`);
|
||||
|
||||
return {
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
alternates: createAlternates(siteLocale, paths),
|
||||
openGraph: {
|
||||
title: post.title,
|
||||
description: post.excerpt,
|
||||
url,
|
||||
type: "article",
|
||||
locale: locale === "en" ? "en_US" : "tr_TR",
|
||||
alternateLocale:
|
||||
translations.length > 1
|
||||
? [locale === "en" ? "tr_TR" : "en_US"]
|
||||
: undefined,
|
||||
publishedTime: post.date,
|
||||
authors: [post.author],
|
||||
images: [
|
||||
@@ -69,7 +86,7 @@ export default async function BlogDetailPage({ params }: BlogDetailPageProps) {
|
||||
<ArticleJsonLd
|
||||
title={post.title}
|
||||
description={post.excerpt}
|
||||
url={`${SITE_URL}/blog/${post.slug}`}
|
||||
url={getLocalizedUrl(locale as SiteLocale, `/blog/${post.slug}`)}
|
||||
image={post.coverImage}
|
||||
datePublished={post.date}
|
||||
authorName={post.author}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import { BlogContent } from "@/components/blog-content";
|
||||
import { getBlogPageData } from "@/data/blog";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
type BlogPageProps = {
|
||||
params: Promise<{ locale: string }>;
|
||||
searchParams?: Promise<{ page?: string | string[]; category?: string | string[]; search?: string | string[] }>;
|
||||
};
|
||||
|
||||
export async function generateMetadata({ params }: BlogPageProps) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({ locale, page: "blog", path: "/blog" });
|
||||
}
|
||||
|
||||
export default async function BlogPage({ params, searchParams }: BlogPageProps) {
|
||||
const { locale } = await params;
|
||||
const resolved = searchParams ? await searchParams : undefined;
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
import { ContactContent } from "@/components/contact-content";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({
|
||||
locale,
|
||||
page: "contact",
|
||||
path: "/contact",
|
||||
});
|
||||
}
|
||||
|
||||
export default function ContactPage() {
|
||||
return <ContactContent />;
|
||||
|
||||
@@ -2,6 +2,20 @@ import { ContentContent } from "@/components/content-content";
|
||||
import { YOUTUBE_VIDEO_LINKS } from "@/data/youtube-videos";
|
||||
import { X_JAVASCRIPT_ANATOMY_VIDEOS } from "@/data/x-videos";
|
||||
import { getPdfNotes } from "@/lib/content-page";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({
|
||||
locale,
|
||||
page: "content",
|
||||
path: "/content",
|
||||
});
|
||||
}
|
||||
|
||||
export default async function ContentPage() {
|
||||
const pdfFiles = await getPdfNotes();
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { GalleryContent } from "@/components/gallery-content";
|
||||
import { GALLERY_IMAGES } from "@/data/gallery";
|
||||
import type { Metadata } from "next";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Galeri",
|
||||
description: "Poyraz Avsever'in tasarımları, projeleri ve görsel içeriklerinden oluşan galeri portföyü.",
|
||||
};
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({
|
||||
locale,
|
||||
page: "gallery",
|
||||
path: "/gallery",
|
||||
});
|
||||
}
|
||||
|
||||
export default function GalleryPage() {
|
||||
return <GalleryContent images={GALLERY_IMAGES} />;
|
||||
|
||||
@@ -30,9 +30,6 @@ export async function generateMetadata({
|
||||
},
|
||||
description: description,
|
||||
applicationName: "Poyraz Avsever Portfolyo",
|
||||
alternates: {
|
||||
canonical: "/",
|
||||
},
|
||||
icons: {
|
||||
icon: [
|
||||
{ url: "/favicon.ico", sizes: "any" },
|
||||
@@ -47,7 +44,6 @@ export async function generateMetadata({
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: locale === "tr" ? "tr_TR" : "en_US",
|
||||
url: "https://poyrazavsever.com",
|
||||
siteName: title,
|
||||
title: title,
|
||||
description: description,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Metadata } from "next";
|
||||
import { LinksContent } from "@/components/links-content";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
type LinksPageProps = {
|
||||
searchParams?: Promise<{
|
||||
@@ -8,35 +8,14 @@ type LinksPageProps = {
|
||||
}>;
|
||||
};
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Links",
|
||||
description:
|
||||
"Poyraz Avsever'in sosyal medya, portfolyo ve içerik bağlantılarına tek sayfadan ulaş.",
|
||||
alternates: {
|
||||
canonical: "/links",
|
||||
},
|
||||
openGraph: {
|
||||
title: "Poyraz Avsever | Links",
|
||||
description:
|
||||
"Poyraz Avsever'in sosyal medya, portfolyo ve içerik bağlantılarına tek sayfadan ulaş.",
|
||||
url: "https://poyrazavsever.com/links",
|
||||
images: [
|
||||
{
|
||||
url: "/logo/cover.png",
|
||||
width: 1536,
|
||||
height: 512,
|
||||
alt: "Poyraz Avsever Links sayfası kapak görseli",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Poyraz Avsever | Links",
|
||||
description:
|
||||
"Poyraz Avsever'in sosyal medya, portfolyo ve içerik bağlantılarına tek sayfadan ulaş.",
|
||||
images: ["/logo/cover.png"],
|
||||
},
|
||||
};
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({ locale, page: "links", path: "/links" });
|
||||
}
|
||||
|
||||
function firstParam(value?: string | string[]) {
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
|
||||
@@ -3,6 +3,21 @@ import { HomeProjectsSection } from "@/components/home-projects-section";
|
||||
import { HomeVideosSection } from "@/components/home-videos-section";
|
||||
import { ReferencesSection } from "@/components/references-section";
|
||||
import { getHomeBlogNews } from "@/data/blog";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({
|
||||
locale,
|
||||
page: "home",
|
||||
path: "/",
|
||||
absoluteTitle: true,
|
||||
});
|
||||
}
|
||||
|
||||
export default async function Home({
|
||||
params,
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
import { ProjectsContent } from "@/components/projects-content";
|
||||
import { getStaticPageMetadata } from "@/lib/seo";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ locale: string }>;
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
return getStaticPageMetadata({
|
||||
locale,
|
||||
page: "projects",
|
||||
path: "/projects",
|
||||
});
|
||||
}
|
||||
|
||||
export default function ProjectsPage() {
|
||||
return <ProjectsContent />;
|
||||
|
||||
Reference in New Issue
Block a user