172 lines
4.7 KiB
TypeScript
172 lines
4.7 KiB
TypeScript
/**
|
|
* OG Image metadata utilities.
|
|
*
|
|
* Builds the /api/og URL with appropriate query params for dynamic
|
|
* Open Graph image generation. Used by page-level metadata exports.
|
|
*/
|
|
|
|
import { BOOK_NAMES, CC_LILAS } from "@/lib/constants";
|
|
|
|
const SITE_URL =
|
|
process.env.NEXT_PUBLIC_SITE_URL || "https://prabhupadasays.org";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Types
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export type OgParams = {
|
|
title: string;
|
|
detail?: string;
|
|
quote?: string;
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Build the /api/og image URL
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Build a fully-qualified URL to the /api/og image endpoint.
|
|
*
|
|
* The URL is kept as short as possible — only non-empty params are included.
|
|
* The quote is truncated to 260 chars to keep URL length reasonable.
|
|
*/
|
|
export function buildOgImageUrl(params: OgParams): string {
|
|
const url = new URL("/api/og", SITE_URL);
|
|
|
|
url.searchParams.set("title", params.title);
|
|
|
|
if (params.detail) {
|
|
url.searchParams.set("detail", params.detail);
|
|
}
|
|
|
|
if (params.quote) {
|
|
const truncated =
|
|
params.quote.length > 260
|
|
? params.quote.slice(0, 257) + "..."
|
|
: params.quote;
|
|
url.searchParams.set("quote", truncated);
|
|
}
|
|
|
|
return url.toString();
|
|
}
|
|
|
|
/**
|
|
* Build OG metadata object for use in Next.js page `metadata` exports.
|
|
*
|
|
* Returns the `openGraph` and `twitter` fields to spread into `Metadata`.
|
|
*/
|
|
export function buildOgMeta(params: OgParams & { description?: string }) {
|
|
const imageUrl = buildOgImageUrl(params);
|
|
const description =
|
|
params.description ||
|
|
params.quote ||
|
|
`${params.title}${params.detail ? ` — ${params.detail}` : ""}`;
|
|
|
|
return {
|
|
openGraph: {
|
|
title: params.title,
|
|
description,
|
|
images: [
|
|
{
|
|
url: imageUrl,
|
|
width: 1200,
|
|
height: 630,
|
|
alt: params.title,
|
|
},
|
|
],
|
|
siteName: "Prabhupāda Says",
|
|
},
|
|
twitter: {
|
|
card: "summary_large_image" as const,
|
|
title: params.title,
|
|
description,
|
|
images: [imageUrl],
|
|
},
|
|
};
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Helpers for common page types
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/** OG metadata for a book page. */
|
|
export function ogForBook(code: string) {
|
|
const title = BOOK_NAMES[code] || code.toUpperCase();
|
|
return buildOgMeta({ title });
|
|
}
|
|
|
|
/** OG metadata for a verse page. */
|
|
export function ogForVerse(
|
|
code: string,
|
|
parts: { division?: string; chapter: number; verse: number },
|
|
) {
|
|
const title = BOOK_NAMES[code] || code.toUpperCase();
|
|
let detail: string;
|
|
|
|
if (code === "sb" && parts.division) {
|
|
detail = `Canto ${parts.division}, Chapter ${parts.chapter}, Verse ${parts.verse}`;
|
|
} else if (code === "cc" && parts.division) {
|
|
const lila = CC_LILAS[parts.division] || parts.division;
|
|
detail = `${lila}, Chapter ${parts.chapter}, Verse ${parts.verse}`;
|
|
} else {
|
|
detail = `Chapter ${parts.chapter}, Verse ${parts.verse}`;
|
|
}
|
|
|
|
return buildOgMeta({ title, detail });
|
|
}
|
|
|
|
/** OG metadata for a prose chapter. */
|
|
export function ogForChapter(code: string, chapterTitle: string) {
|
|
const bookTitle = BOOK_NAMES[code] || code.toUpperCase();
|
|
return buildOgMeta({ title: bookTitle, detail: chapterTitle });
|
|
}
|
|
|
|
/** OG metadata for an essay. */
|
|
export function ogForEssay(title: string) {
|
|
return buildOgMeta({
|
|
title,
|
|
detail: "Essay by Śrīla Prabhupāda",
|
|
});
|
|
}
|
|
|
|
/** OG metadata for a letter. */
|
|
export function ogForLetter(recipient: string, meta?: string) {
|
|
return buildOgMeta({
|
|
title: `Letter to ${recipient}`,
|
|
detail: meta || undefined,
|
|
});
|
|
}
|
|
|
|
/** OG metadata for a journal entry. */
|
|
export function ogForJournal(journalTitle: string, entryTitle?: string) {
|
|
return buildOgMeta({
|
|
title: journalTitle,
|
|
detail: entryTitle || undefined,
|
|
});
|
|
}
|
|
|
|
/** OG metadata for a magazine issue. */
|
|
export function ogForMagazine(magazineTitle: string, issueTitle?: string) {
|
|
return buildOgMeta({
|
|
title: magazineTitle,
|
|
detail: issueTitle || undefined,
|
|
});
|
|
}
|
|
|
|
/** OG metadata for an other document chapter. */
|
|
export function ogForOtherDocument(docTitle: string, chapterTitle?: string) {
|
|
return buildOgMeta({
|
|
title: docTitle,
|
|
detail: chapterTitle || undefined,
|
|
});
|
|
}
|
|
|
|
/** Default OG metadata for the site. */
|
|
export function ogDefault() {
|
|
return buildOgMeta({
|
|
title: "Prabhupāda Says",
|
|
description:
|
|
"Browse the books and teachings of His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda",
|
|
});
|
|
}
|