docs(metadata): centralize SEO metadata with createMetadata helper (#8486)

This commit is contained in:
Sandy
2026-03-11 10:29:56 -07:00
committed by Alex Yang
parent 362df86d78
commit 12f16c371e
12 changed files with 95 additions and 65 deletions
+5 -4
View File
@@ -7,6 +7,7 @@ import Link from "next/link";
import { notFound } from "next/navigation";
import { BlogLeftPanel } from "@/components/blog/blog-left-panel";
import { Callout } from "@/components/ui/callout";
import { createMetadata } from "@/lib/metadata";
import { blogs } from "@/lib/source";
import { cn } from "@/lib/utils";
@@ -270,10 +271,10 @@ export async function generateMetadata({
}) {
const { slug } = await params;
if (!slug) {
return {
return createMetadata({
title: "Blog - Better Auth",
description: "Latest updates, articles, and insights about Better Auth",
};
});
}
const page = blogs.getPage(slug);
if (!page || page.data.draft) return notFound();
@@ -296,7 +297,7 @@ export async function generateMetadata({
const ogImage = image || ogUrl;
return {
return createMetadata({
title,
description,
openGraph: {
@@ -311,7 +312,7 @@ export async function generateMetadata({
description,
images: [ogImage],
},
};
});
}
export function generateStaticParams() {
+21 -8
View File
@@ -1,21 +1,34 @@
import { RootProvider } from "fumadocs-ui/provider/next";
import type { Metadata } from "next";
import { createMetadata } from "@/lib/metadata";
export const metadata: Metadata = {
title: "Blog - Better Auth",
description: "Latest updates, articles, and insights about Better Auth",
const description = "Latest updates, articles, and insights about Better Auth";
export const metadata: Metadata = createMetadata({
title: "Blog",
description,
openGraph: {
url: "/blog",
title: "Blog - Better Auth",
description: "Latest updates, articles, and insights about Better Auth",
description,
images: ["/api/og-release?heading=Better%20Auth%20Blog"],
},
twitter: {
card: "summary_large_image",
title: "Blog - Better Auth",
description: "Latest updates, articles, and insights about Better Auth",
images: ["/api/og-release?heading=Better%20Auth%20Blog"],
title: "Blog - Better Auth",
description,
},
};
alternates: {
types: {
"application/rss+xml": [
{
title: "Better Auth Blog",
url: "https://better-auth.com/blog/rss.xml",
},
],
},
},
});
export default function BlogLayout({
children,
+3 -2
View File
@@ -1,10 +1,11 @@
import type { Metadata } from "next";
import { createMetadata } from "@/lib/metadata";
import { CareersPageClient } from "./careers-client";
export const metadata: Metadata = {
export const metadata: Metadata = createMetadata({
title: "Careers",
description: "Join the Better Auth team — open positions and how to apply.",
};
});
export default function CareersPage() {
return <CareersPageClient />;
+4 -3
View File
@@ -1,5 +1,6 @@
import Link from "next/link";
import { HalftoneBackground } from "@/components/landing/halftone-bg";
import { createMetadata } from "@/lib/metadata";
import { ChangelogContent } from "./changelog-content";
export const dynamic = "force-static";
@@ -148,7 +149,7 @@ export default async function ChangelogPage() {
);
}
export const metadata = {
title: "Changelog - Better Auth",
export const metadata = createMetadata({
title: "Changelog",
description: "Latest changes, fixes, and updates to Better Auth",
};
});
+3 -2
View File
@@ -1,12 +1,13 @@
import type { Metadata } from "next";
import { getCommunityStats } from "@/lib/community-stats";
import { createMetadata } from "@/lib/metadata";
import { CommunityPageClient } from "./community-client";
export const metadata: Metadata = {
export const metadata: Metadata = createMetadata({
title: "Community",
description:
"Join the Better Auth community — contributors, Discord members, and ecosystem stats.",
};
});
export const revalidate = 21600; // Revalidate every 6 hours
+3 -2
View File
@@ -24,6 +24,7 @@ import {
GenerateSecret,
} from "@/components/docs/mdx-components";
import { Callout } from "@/components/ui/callout";
import { createMetadata } from "@/lib/metadata";
import { getSource } from "@/lib/source";
import { cn } from "@/lib/utils";
import { LLMCopyButton, ViewOptions } from "./page.client";
@@ -164,7 +165,7 @@ export async function generateMetadata({
const ogUrl = `/api/og?${ogSearchParams.toString()}`;
return {
return createMetadata({
title: page.data.title,
description: page.data.description,
openGraph: {
@@ -186,5 +187,5 @@ export async function generateMetadata({
description: page.data.description,
images: [ogUrl],
},
};
});
}
+3 -2
View File
@@ -1,11 +1,12 @@
import type { Metadata } from "next";
import { createMetadata } from "@/lib/metadata";
import { EnterprisePageClient } from "./enterprise-client";
export const metadata: Metadata = {
export const metadata: Metadata = createMetadata({
title: "Enterprise",
description:
"Better Auth for enterprise — SSO, SAML, audit logs, and dedicated support.",
};
});
export default function EnterprisePage() {
return <EnterprisePageClient />;
+3 -32
View File
@@ -7,6 +7,7 @@ import Script from "next/script";
import type { ReactNode } from "react";
import { StaggeredNavFiles } from "@/components/landing/staggered-nav-files";
import { Providers } from "@/components/providers";
import { createMetadata } from "@/lib/metadata";
const fontSans = Geist({
subsets: ["latin"],
@@ -18,43 +19,13 @@ const fontMono = Geist_Mono({
variable: "--font-mono",
});
export const metadata: Metadata = {
metadataBase: new URL(
process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: process.env.NODE_ENV === "production"
? "https://better-auth.com"
: (process.env.NEXT_PUBLIC_URL ?? "http://localhost:3000"),
),
export const metadata: Metadata = createMetadata({
title: {
template: "%s | Better Auth",
default: "Better Auth",
},
description: "The Most Comprehensive Authentication Framework",
icons: {
icon: [
{ url: "/favicon/favicon.ico", sizes: "any" },
{
url: "/favicon/favicon-32x32.png",
sizes: "32x32",
type: "image/png",
},
{
url: "/favicon/favicon-16x16.png",
sizes: "16x16",
type: "image/png",
},
],
apple: "/favicon/apple-touch-icon.png",
},
openGraph: {
images: ["/og.png"],
},
twitter: {
card: "summary_large_image",
images: ["/og.png"],
},
};
});
export default function RootLayout({ children }: { children: ReactNode }) {
return (
+2 -1
View File
@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { createMetadata } from "@/lib/metadata";
import { FrameworkContent } from "./_components/framework-content";
import { InfrastructureContent } from "./_components/infrastructure-content";
@@ -30,7 +31,7 @@ export async function generateMetadata({
const { tab } = await params;
const meta = tabs[tab as Tab];
if (!meta) return {};
return { title: meta.title, description: meta.description };
return createMetadata({ title: meta.title, description: meta.description });
}
export default async function TabPage({
+47
View File
@@ -0,0 +1,47 @@
import type { Metadata } from "next";
export function createMetadata(override: Metadata): Metadata {
return {
...override,
metadataBase: baseUrl,
openGraph: {
title: override.title ?? undefined,
description: override.description ?? undefined,
url: "https://better-auth.com",
images: "/og.png",
siteName: "Better Auth",
...override.openGraph,
},
twitter: {
card: "summary_large_image",
title: override.title ?? undefined,
description: override.description ?? undefined,
images: "/og.png",
...override.twitter,
},
icons: {
icon: [
{ url: "/favicon/favicon.ico", sizes: "any" },
{
url: "/favicon/favicon-32x32.png",
sizes: "32x32",
type: "image/png",
},
{
url: "/favicon/favicon-16x16.png",
sizes: "16x16",
type: "image/png",
},
],
apple: "/favicon/apple-touch-icon.png",
},
};
}
export const baseUrl =
process.env.NODE_ENV === "development" ||
(!process.env.VERCEL_PROJECT_PRODUCTION_URL && !process.env.VERCEL_URL)
? new URL("http://localhost:3000")
: new URL(
`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL || process.env.VERCEL_URL}`,
);
+1 -1
View File
@@ -1,6 +1,6 @@
import { Feed } from "feed";
import { baseUrl } from "./metadata";
import { blogs } from "./source";
import { baseUrl } from "./utils";
export function getRSS() {
const feed = new Feed({
-8
View File
@@ -19,11 +19,3 @@ export function mergeRefs<T>(
});
};
}
export const baseUrl =
process.env.NODE_ENV === "development" ||
(!process.env.VERCEL_PROJECT_PRODUCTION_URL && !process.env.VERCEL_URL)
? new URL("http://localhost:3000")
: new URL(
`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL || process.env.VERCEL_URL}`,
);