Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122import type { Metadata } from "next";
import type { MDXData } from "../../content/utils";
export const TITLE = "openstatus";export const HOMEPAGE_TITLE = "Free & Open Source Status Page and Uptime Monitoring";export const DESCRIPTION = "Open source status page and uptime monitoring. Keep it in code, let your agents update it. Free to start, self-hostable.";
export const OG_DESCRIPTION = "The status page for humans and agents";
export const BASE_URL = process.env.NODE_ENV === "production" ? "https://www.openstatus.dev" : "http://localhost:3000";
export const APP_URL = "https://app.openstatus.dev";
export const twitterMetadata: Metadata["twitter"] = { title: TITLE, description: DESCRIPTION, card: "summary_large_image", images: ["/api/og"],};
export const ogMetadata: Metadata["openGraph"] = { title: TITLE, description: DESCRIPTION, type: "website", images: ["/api/og"],};
export const defaultMetadata: Metadata = { title: { template: `%s | ${TITLE}`, default: HOMEPAGE_TITLE, }, description: DESCRIPTION, metadataBase: new URL(BASE_URL), alternates: { canonical: "/", }, twitter: twitterMetadata, openGraph: ogMetadata,};
// Next merges metadata shallowly per field, so a page must emit its own// og/twitter blocks or it inherits the root layout's generic ones wholesale.export const getSocialMetadata = (args: { title: string; description: string; url: string; category?: string; ogImage?: string;}): Pick<Metadata, "openGraph" | "twitter"> => { const { title, description, url, category, ogImage: ogImageOverride } = args;
const searchParams = new URLSearchParams({ title, description }); if (category) searchParams.set("category", category); const ogImage = ogImageOverride ?? `${BASE_URL}/api/og?${searchParams.toString()}`;
return { openGraph: { title, description, type: "website", url, images: [ { url: ogImage, }, ], }, twitter: { card: "summary_large_image", title, description, images: [ogImage], }, };};
export const getPageMetadata = (page: MDXData, basePath?: string): Metadata => { const { slug, metadata } = page; const { title, description, category, publishedAt, updatedAt, seo } = metadata;
const url = basePath ? `${BASE_URL}/${basePath}/${slug}` : `${BASE_URL}/${slug}`;
const metaTitle = seo?.title ?? title; const metaDescription = seo?.description ?? description;
const { openGraph, twitter } = getSocialMetadata({ title: metaTitle, description: metaDescription, url, category, ogImage: seo?.ogImage, });
return { // `absolute` bypasses the `%s | openstatus` template so the override is verbatim title: seo?.title ? { absolute: seo.title } : title, description: metaDescription, alternates: { canonical: seo?.canonical ?? url, }, ...(seo?.noindex ? { robots: { index: false } } : {}), openGraph: { ...openGraph, type: "article", publishedTime: publishedAt.toISOString(), modifiedTime: (updatedAt ?? publishedAt).toISOString(), }, twitter, };};