import { Metadata } from 'next' if (!process.env.SITE_URL) { throw new Error('SITE_URL environment variable is not set (e.g. SITE_URL=https://example.com)') } export const SITE_URL = process.env.SITE_URL.replace(/\/$/, '') export const SITE_NAME = 'Ephemeris' export const SITE_DESCRIPTION = 'A blog about me and my interests' export const AUTHOR = { name: 'Frank Borisjuk', handle: 'hangerthem', url: SITE_URL + '/about' } // Child segments replace `alternates` wholesale, so every page re-declares the feed link const feedAlternate = { 'application/atom+xml': [{ url: '/feed.xml', title: SITE_NAME }] } export const metadata: Metadata = { metadataBase: new URL(SITE_URL), title: SITE_NAME, description: SITE_DESCRIPTION, creator: AUTHOR.handle, authors: [{ name: AUTHOR.name, url: AUTHOR.url }], alternates: { types: feedAlternate }, openGraph: { type: 'website', title: SITE_NAME, description: SITE_DESCRIPTION, url: SITE_URL, siteName: SITE_NAME, }, twitter: { card: 'summary_large_image', title: SITE_NAME, description: SITE_DESCRIPTION, }, appleWebApp: { title: SITE_NAME, statusBarStyle: 'default', capable: true, }, } type PageMetadataOptions = { title: string description: string /** Path relative to the site root, starting with a slash. */ path: string /** Open Graph / Twitter image URL. Defaults to the generated site card. */ image?: string openGraph?: Metadata['openGraph'] } // Generated by app/opengraph-image.tsx. Child segments that set `openGraph` don't inherit // file-based images, and explicit images win over them, so every page names its image here. const defaultOgImage = '/opengraph-image' /** Builds consistent page metadata (title, canonical URL, Open Graph and Twitter card). */ export function pageMetadata({ title, description, path, image = defaultOgImage, openGraph, }: PageMetadataOptions): Metadata { const fullTitle = `${title} | ${SITE_NAME}` return { title: fullTitle, description, alternates: { canonical: path, types: feedAlternate }, openGraph: { type: 'website', title: fullTitle, description, url: SITE_URL + path, siteName: SITE_NAME, images: image, ...openGraph, }, twitter: { card: 'summary_large_image', title: fullTitle, description, images: image, }, } }