Files
spsays-training/lib/og.ts
T
2026-05-06 00:40:24 +05:30

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",
});
}