import type { Metadata } from 'next' interface Profile { businessName: string | null locality: string | null logoUrl: string | null siteUrl: string | null } async function profile(): Promise { const base = process.env.NEXT_PUBLIC_VULA_COMMERCE_URL const id = process.env.NEXT_PUBLIC_VULA_PROJECT_ID if (!base || !id) return null try { const res = await fetch(base + '/api/public/profile/' + id, { next: { revalidate: 3600 } }) return res.ok ? ((await res.json())?.profile ?? null) : null } catch { return null } } /** * A title for one section of the site. * * "Services | Riverside Dental, Melville" — the section first, because * Google truncates the end and the section is what distinguishes this page * from every other page on the site. The town is included when we know it: * someone searching "chiropractor Richards Bay" is searching for the town as * much as the trade. * * Falls back to the bare section name. A title that says "Services" is worse * than one that says "Services | Riverside Dental" and far better than a * template that reads "Services | undefined". */ export async function sectionMetadata(section: string, description?: string): Promise { const p = await profile() const where = p?.businessName ? p.locality ? p.businessName + ', ' + p.locality : p.businessName : null const title = where ? section + ' | ' + where : section return { title, ...(description ? { description } : {}), // The card WhatsApp, Facebook and Slack show when someone pastes the link. // Without og: tags they fall back to the title and description, which is why // a share already reads correctly — the picture is the only thing missing. // // Her own logo, or nothing. Never a stock photograph: the same one can end // up on several sites, and a gleaming clinic on the card with a modest room // at the other end is the kind of overselling this whole pass removed. openGraph: { title, ...(description ? { description } : {}), ...(p?.businessName ? { siteName: p.businessName } : {}), ...(p?.siteUrl ? { url: p.siteUrl } : {}), type: 'website', locale: 'en_ZA', ...(p?.logoUrl ? { images: [{ url: p.logoUrl }] } : {}), }, } } /** * A page that must never appear in search results. * * A customer's own booking page is reached from a WhatsApp message with a * code in the link. Those links get forwarded, pasted into groups and picked * up, and a booking of hers turning up in Google is a breach she would hear * about from the patient, not from us. Checkout and account pages are the * same: private by purpose, not by obscurity. */ export function privatePage(section: string): Metadata { return { title: section, robots: { index: false, follow: false }, } }