import { getSEOSettingsGlobal } from "@/lib/payload/globals"; import { siteConfig } from "@/lib/site"; function stripTrailingSlash(url: string): string { return url.replace(/\/+$/, ""); } /** * The canonical base URL for the whole site. Prefers the CMS override * (SEO-Einstellungen → Website-URL) when it's a valid absolute URL, then * NEXT_PUBLIC_SERVER_URL (the single source of truth used everywhere else * in this app — emails, meeting links, Payload's own serverURL), then the * hardcoded siteConfig fallback. Never throws — SEO metadata must never * break a page render. */ export async function getSiteUrl(): Promise { try { const settings = await getSEOSettingsGlobal(); if (settings.siteUrl && /^https?:\/\/.+/.test(settings.siteUrl)) { return stripTrailingSlash(settings.siteUrl); } } catch { // CMS/DB unreachable — fall through to the env-based default. } return stripTrailingSlash(process.env.NEXT_PUBLIC_SERVER_URL || siteConfig.domain); } /** Whether the site should be indexable at all (global kill switch in the CMS). */ export async function isSiteIndexable(): Promise { try { const settings = await getSEOSettingsGlobal(); return settings.robotsIndexable !== false; } catch { return true; } }