diff --git a/apps/web/src/app/blog/[slug]/page.tsx b/apps/web/src/app/blog/[slug]/page.tsx index 7e6eafe42..065d22d09 100644 --- a/apps/web/src/app/blog/[slug]/page.tsx +++ b/apps/web/src/app/blog/[slug]/page.tsx @@ -3,6 +3,11 @@ import Link from "next/link"; import { notFound } from "next/navigation"; import { allPosts } from "contentlayer/generated"; +import { + defaultMetadata, + ogMetadata, + twitterMetadata, +} from "@/app/shared-metadata"; import { Mdx } from "@/components/content/mdx"; import { Shell } from "@/components/dashboard/shell"; import { BackButton } from "@/components/layout/back-button"; @@ -29,9 +34,11 @@ export async function generateMetadata({ const { title, publishedAt: publishedTime, description, slug, image } = post; return { + ...defaultMetadata, title, description, openGraph: { + ...ogMetadata, title, description, type: "article", @@ -44,7 +51,7 @@ export async function generateMetadata({ ], }, twitter: { - card: "summary_large_image", + ...twitterMetadata, title, description, images: [ diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 23d45f173..7c1f7003f 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -6,6 +6,11 @@ import LocalFont from "next/font/local"; import { ClerkProvider } from "@clerk/nextjs"; import PlausibleProvider from "next-plausible"; +import { + defaultMetadata, + ogMetadata, + twitterMetadata, +} from "@/app/shared-metadata"; import { TailwindIndicator } from "@/components/tailwind-indicator"; import { Toaster } from "@/components/ui/toaster"; import { ClientAnalytics } from "./_components/analytics"; @@ -18,25 +23,13 @@ const calSans = LocalFont({ variable: "--font-calsans", }); -const TITLE = "OpenStatus"; -const DESCRIPTION = - "Open-Source uptime monitoring with beautiful status pages."; - export const metadata: Metadata = { - title: TITLE, - description: DESCRIPTION, - metadataBase: new URL("https://www.openstatus.dev"), + ...defaultMetadata, twitter: { - images: [`/api/og`], - card: "summary_large_image", - title: TITLE, - description: DESCRIPTION, + ...twitterMetadata, }, openGraph: { - type: "website", - images: [`/api/og`], - title: TITLE, - description: DESCRIPTION, + ...ogMetadata, }, }; diff --git a/apps/web/src/app/play/layout.tsx b/apps/web/src/app/play/layout.tsx index 84b014ee0..40370b430 100644 --- a/apps/web/src/app/play/layout.tsx +++ b/apps/web/src/app/play/layout.tsx @@ -1,29 +1,24 @@ import * as React from "react"; import type { Metadata } from "next"; +import { + defaultMetadata, + ogMetadata, + twitterMetadata, +} from "@/app/shared-metadata"; import { Shell } from "@/components/dashboard/shell"; import { BackButton } from "@/components/layout/back-button"; import { MarketingLayout } from "@/components/layout/marketing-layout"; -const TITLE = "OpenStatus"; -const DESCRIPTION = - "Open-Source alternative to your current monitoring service with beautiful status page"; - export const metadata: Metadata = { - title: TITLE, - description: DESCRIPTION, - metadataBase: new URL("https://www.openstatus.dev"), + ...defaultMetadata, twitter: { + ...twitterMetadata, images: [`/api/og?monitorId=openstatus`], - card: "summary_large_image", - title: TITLE, - description: DESCRIPTION, }, openGraph: { - type: "website", + ...ogMetadata, images: [`/api/og?monitorId=openstatus`], - title: TITLE, - description: DESCRIPTION, }, }; diff --git a/apps/web/src/app/shared-metadata.ts b/apps/web/src/app/shared-metadata.ts new file mode 100644 index 000000000..0d6d9ca99 --- /dev/null +++ b/apps/web/src/app/shared-metadata.ts @@ -0,0 +1,23 @@ +const TITLE = "OpenStatus"; +const DESCRIPTION = + "Open-Source uptime monitoring with beautiful status pages."; + +export const defaultMetadata = { + title: TITLE, + description: DESCRIPTION, + metadataBase: new URL("https://www.openstatus.dev"), +}; + +export const twitterMetadata = { + title: TITLE, + description: DESCRIPTION, + card: "summary_large_image", + images: [`/api/og`], +}; + +export const ogMetadata = { + title: TITLE, + description: DESCRIPTION, + type: "website", + images: [`/api/og`], +}; diff --git a/apps/web/src/app/status-page/[domain]/page.tsx b/apps/web/src/app/status-page/[domain]/page.tsx index a8c9ded7d..e6ff610d4 100644 --- a/apps/web/src/app/status-page/[domain]/page.tsx +++ b/apps/web/src/app/status-page/[domain]/page.tsx @@ -1,6 +1,11 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; +import { + defaultMetadata, + ogMetadata, + twitterMetadata, +} from "@/app/shared-metadata"; import { Header } from "@/components/dashboard/header"; import { Shell } from "@/components/dashboard/shell"; import { IncidentList } from "@/components/status-page/incident-list"; @@ -13,7 +18,7 @@ type Props = { }; export default async function Page({ params }: Props) { - // We should fetch the the monitors and incident here + // We should fetch the monitors and incident here // also the page information if (!params.domain) return notFound(); const page = await api.page.getPageBySlug.query({ slug: params.domain }); @@ -41,21 +46,22 @@ export async function generateMetadata({ params }: Props): Promise { const firstMonitor = page?.monitors?.[0]; // temporary solution return { + ...defaultMetadata, title: page?.title, description: page?.description, icons: page?.icon, twitter: { + ...twitterMetadata, images: [ `/api/og?monitorId=${firstMonitor?.id}&title=${page?.title}&description=${ page?.description || `The ${page?.title} status page}` }`, ], - card: "summary_large_image", title: page?.title, description: page?.description, }, openGraph: { - type: "website", + ...ogMetadata, images: [ `/api/og?monitorId=${firstMonitor?.id}&title=${page?.title}&description=${ page?.description || `The ${page?.title} status page}`