This commit is contained in:
Vula Builder
2026-09-15 18:02:55 +00:00
parent 60fcd2f8c7
commit 3d3e243a30
+81
View File
@@ -0,0 +1,81 @@
import type { Metadata } from 'next'
interface Profile {
businessName: string | null
locality: string | null
logoUrl: string | null
siteUrl: string | null
}
async function profile(): Promise<Profile | null> {
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<Metadata> {
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 },
}
}