feat(seo): add sitemap generator

This commit is contained in:
gosangam
2026-06-15 13:52:12 +05:30
parent 6cc9285bad
commit be4c2f17fe
83 changed files with 633 additions and 8 deletions
+2
View File
@@ -1,3 +1,5 @@
NEXT_PUBLIC_SITE_URL=https://prabhupadasays.org
# BFF API Server (server-side fetches)
BFF_URL=http://localhost:8080
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function BbdChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/bbd/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Beyond Birth and Death" })} />
<PageHeader sticky>
<Link
href="/books/bbd"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getBbdMeta, getBbdIntroSegments } from "@/lib/bbd";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function BbdPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/bbd", name: "Beyond Birth and Death" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -4,6 +4,8 @@ import { notFound } from "next/navigation";
import { getBookMeta, getProseChapters } from "@/lib/api";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { ExtractedVerseCount } from "../extracted-verse-count";
@@ -34,6 +36,7 @@ export default async function BgPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/bg", name: "Bhagavad-gītā As It Is" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -11,6 +11,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -63,6 +65,7 @@ export default async function BkChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/bk/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Bhagavāner Kathā" })} />
<PageHeader sticky>
<Link
href="/books/bk"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getBkMeta } from "@/lib/bk";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -18,6 +20,7 @@ export default async function BkPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/bk", name: "Bhagavāner Kathā" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getBookMeta } from "@/lib/api";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { ExtractedVerseCount } from "../extracted-verse-count";
import fs from "fs";
@@ -80,6 +82,7 @@ export default async function BsPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/bs", name: "Śrī Brahma-saṁhitā" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -11,6 +11,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -63,6 +65,7 @@ export default async function CbhcChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/cbhc/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Śrī Caitanya-bhāgavata Commentary" })} />
<PageHeader sticky>
<Link
href="/books/cbhc"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getCbhcMeta } from "@/lib/cbhc";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -18,6 +20,7 @@ export default async function CbhcPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/cbhc", name: "Śrī Caitanya-bhāgavata Commentary" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -3,6 +3,8 @@ import Link from "next/link";
import { getBookMeta, getProseChapters } from "@/lib/api";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { ExtractedVerseCount } from "../extracted-verse-count";
@@ -44,6 +46,7 @@ export default async function CcPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/cc", name: "Śrī Caitanya-caritāmṛta" })} />
<PageHeader>
<Link
href="/books"
+16
View File
@@ -7,6 +7,9 @@ import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ChevronLeft, ChevronRight, Loader2 } from "lucide-react";
import { MobileNav, type MobileNavGroup } from "@/components/layout/mobile-nav";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { BOOK_NAMES } from "@/lib/constants";
// ---------------------------------------------------------------------------
// Types
@@ -389,6 +392,19 @@ export function ChapterViewer({
return (
<>
{/* Structured data for the currently-shown verse (SSR'd for the initial
verse, updates on client navigation). */}
{currentVerse ? (
<JsonLd
data={articleJsonLd({
path: `${basePath}/${currentVerseNum}`,
headline: `${BOOK_NAMES[book] ?? book} ${currentVerse.reference}`,
description: currentVerse.translation,
isPartOf: BOOK_NAMES[book] ?? book,
})}
/>
) : null}
{/* ---- Sidebar: Verse Index ---- */}
{/* Sticky sidebar. The max-h leaves 76px at the viewport bottom for
the site footer so the sidebar doesn't slide behind it when the
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -77,6 +79,7 @@ export default async function DsChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/ds/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Dialectic Spiritualism" })} />
<PageHeader sticky>
<Link
href="/books/ds"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getDsMeta, getDsIntroSegments } from "@/lib/ds";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function DsPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/ds", name: "Dialectic Spiritualism" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function EjChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/ej/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Easy Journey to Other Planets" })} />
<PageHeader sticky>
<Link
href="/books/ej"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getEjMeta, getEjIntroSegments } from "@/lib/ej";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function EjPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/ej", name: "Easy Journey to Other Planets" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function EkChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/ek/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Elevation to Kṛṣṇa Consciousness" })} />
<PageHeader sticky>
<Link
href="/books/ek"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getEkMeta, getEkIntroSegments } from "@/lib/ek";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function EkPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/ek", name: "Elevation to Kṛṣṇa Consciousness" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -11,6 +11,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -67,6 +69,7 @@ export default async function GgChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/gg/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Gītār Gān" })} />
<PageHeader sticky>
<Link
href="/books/gg"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getGgMeta, getGgIntroSegments } from "@/lib/gg";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function GgPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/gg", name: "Gītār Gān" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function HkhChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/hkh/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "The Kṛṣṇa Consciousness Handbook" })} />
<PageHeader sticky>
<Link
href="/books/hkh"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getHkhMeta, getHkhIntroSegments } from "@/lib/hkh";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function HkhPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/hkh", name: "The Kṛṣṇa Consciousness Handbook" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -12,6 +12,8 @@ import {
} from "@/lib/iso";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -103,6 +105,7 @@ export default async function IsoMantraPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/iso/${slug}`, headline: content.title ?? "Śrī Īśopaniṣad", isPartOf: "Śrī Īśopaniṣad" })} />
<PageHeader sticky>
<Link
href="/books/iso"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getIsoMeta, getIsoIntroSegments } from "@/lib/iso";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -28,6 +30,7 @@ export default async function IsoPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/iso", name: "Śrī Īśopaniṣad" })} />
<PageHeader>
<Link
href="/books"
@@ -7,6 +7,8 @@ import { getProseChapter, getProseChapters } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -66,6 +68,7 @@ export default async function KbChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/kb/${vol}/${slug}`, headline: chapter.title, description: chapter.paragraphs?.[0], isPartOf: "Kṛṣṇa, The Supreme Personality of Godhead" })} />
<PageHeader sticky>
<Link
href={`/books/kb/${vol}`}
+3
View File
@@ -4,6 +4,8 @@ import { notFound } from "next/navigation";
import { getBookMeta } from "@/lib/api";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
@@ -27,6 +29,7 @@ export default async function KbPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/kb", name: "Kṛṣṇa, The Supreme Personality of Godhead" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function LclChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/lcl/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Life Comes from Life" })} />
<PageHeader sticky>
<Link
href="/books/lcl"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getLclMeta, getLclIntroSegments } from "@/lib/lcl";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function LclPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/lcl", name: "Life Comes from Life" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -67,6 +69,7 @@ export default async function LobChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/lob/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Light of the Bhāgavata" })} />
<PageHeader sticky>
<Link
href="/books/lob"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getLobMeta, getLobIntroSegments } from "@/lib/lob";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function LobPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/lob", name: "Light of the Bhāgavata" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -67,6 +69,7 @@ export default async function MgChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/mg/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Kṛṣṇa Consciousness: The Matchless Gift" })} />
<PageHeader sticky>
<Link
href="/books/mg"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getMgMeta, getMgIntroSegments } from "@/lib/mg";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function MgPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/mg", name: "Kṛṣṇa Consciousness: The Matchless Gift" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getBookMeta } from "@/lib/api";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { ExtractedVerseCount } from "../extracted-verse-count";
import fs from "fs";
@@ -79,6 +81,7 @@ export default async function MmPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/mm", name: "Mukunda-mālā-stotra" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function MogChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/mog/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Message of Godhead" })} />
<PageHeader sticky>
<Link
href="/books/mog"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getMogMeta, getMogIntroSegments } from "@/lib/mog";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function MogPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/mog", name: "Message of Godhead" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getBookMeta } from "@/lib/api";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { ExtractedVerseCount } from "../extracted-verse-count";
import fs from "fs";
@@ -79,6 +81,7 @@ export default async function NbsPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/nbs", name: "Nārada-bhakti-sūtra" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function NodChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/nod/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "The Nectar of Devotion" })} />
<PageHeader sticky>
<Link
href="/books/nod"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getNodMeta, getNodIntroSegments } from "@/lib/nod";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -27,6 +29,7 @@ export default async function NodPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/nod", name: "The Nectar of Devotion" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -12,6 +12,8 @@ import {
} from "@/lib/noi";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -94,6 +96,7 @@ export default async function NoiTextPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/noi/${slug}`, headline: content.title ?? "The Nectar of Instruction", isPartOf: "The Nectar of Instruction" })} />
<PageHeader sticky>
<Link
href="/books/noi"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getNoiMeta, getNoiIntroSegments } from "@/lib/noi";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function NoiPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/noi", name: "The Nectar of Instruction" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function OchkmChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/ochkm/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "On Chanting Hare Kṛṣṇa" })} />
<PageHeader sticky>
<Link
href="/books/ochkm"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getOchkmMeta, getOchkmIntroSegments } from "@/lib/ochkm";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function OchkmPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/ochkm", name: "On Chanting Hare Kṛṣṇa" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function OwkChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/owk/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "On the Way to Kṛṣṇa" })} />
<PageHeader sticky>
<Link
href="/books/owk"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getOwkMeta, getOwkIntroSegments } from "@/lib/owk";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function OwkPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/owk", name: "On the Way to Kṛṣṇa" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -66,6 +68,7 @@ export default async function PkChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/pk/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Prabhupāda-Kṛpā" })} />
<PageHeader sticky>
<Link
href="/books/pk"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getPkMeta } from "@/lib/pk";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -18,6 +20,7 @@ export default async function PkPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/pk", name: "Prabhupāda-Kṛpā" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function PoyChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/poy/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "The Perfection of Yoga" })} />
<PageHeader sticky>
<Link
href="/books/poy"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getPoyMeta, getPoyIntroSegments } from "@/lib/poy";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function PoyPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/poy", name: "The Perfection of Yoga" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function PqpaChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/pqpa/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Perfect Questions, Perfect Answers" })} />
<PageHeader sticky>
<Link
href="/books/pqpa"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getPqpaMeta, getPqpaIntroSegments } from "@/lib/pqpa";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function PqpaPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/pqpa", name: "Perfect Questions, Perfect Answers" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function RvChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/rv/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Rāja-vidyā: The King of Knowledge" })} />
<PageHeader sticky>
<Link
href="/books/rv"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getRvMeta, getRvIntroSegments } from "@/lib/rv";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -20,6 +22,7 @@ export default async function RvPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/rv", name: "Rāja-vidyā: The King of Knowledge" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -1,6 +1,8 @@
import type { Metadata } from "next";
import Link from "next/link";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { ExtractedVerseCount } from "../extracted-verse-count";
@@ -42,6 +44,7 @@ export default async function SbPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/sb", name: "Śrīmad-Bhāgavatam" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -4,6 +4,8 @@ import { notFound } from "next/navigation";
import { getBookMeta } from "@/lib/api";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { ExtractedVerseCount } from "../extracted-verse-count";
@@ -32,6 +34,7 @@ export default async function Sb1962Page() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/sb1962", name: "Śrīmad-Bhāgavatam (1962 Edition)" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -77,6 +79,7 @@ export default async function SsrChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/ssr/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "The Science of Self-Realization" })} />
<PageHeader sticky>
<Link
href="/books/ssr"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getSsrMeta, getSsrIntroSegments } from "@/lib/ssr";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function SsrPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/ssr", name: "The Science of Self-Realization" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -14,6 +14,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -78,6 +80,7 @@ export default async function SvaChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/sva/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Songs of the Vaiṣṇava Ācāryas" })} />
<PageHeader sticky>
<Link
href="/books/sva"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getSvaMeta, getSvaIntroSegments } from "@/lib/sva";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function SvaPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/sva", name: "Songs of the Vaiṣṇava Ācāryas" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function TlcChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/tlc/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Teachings of Lord Caitanya" })} />
<PageHeader sticky>
<Link
href="/books/tlc"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getTlcMeta, getTlcIntroSegments } from "@/lib/tlc";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -25,6 +27,7 @@ export default async function TlcPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/tlc", name: "Teachings of Lord Caitanya" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function TlkChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/tlk/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Teachings of Lord Kapila" })} />
<PageHeader sticky>
<Link
href="/books/tlk"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getTlkMeta, getTlkIntroSegments } from "@/lib/tlk";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function TlkPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/tlk", name: "Teachings of Lord Kapila" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function TqkChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/tqk/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Teachings of Queen Kuntī" })} />
<PageHeader sticky>
<Link
href="/books/tqk"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getTqkMeta, getTqkIntroSegments } from "@/lib/tqk";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -24,6 +26,7 @@ export default async function TqkPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/tqk", name: "Teachings of Queen Kuntī" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -13,6 +13,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -71,6 +73,7 @@ export default async function TtpChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/ttp/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Teachings of Lord Kapila" })} />
<PageHeader sticky>
<Link
href="/books/ttp"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getTtpMeta } from "@/lib/ttp";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -18,6 +20,7 @@ export default async function TtpPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/ttp", name: "Teachings of Lord Kapila" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -12,6 +12,8 @@ import { getProseChapter } from "@/lib/api";
import { ogForChapter, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { BOOK_NAMES } from "@/lib/constants";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -63,6 +65,7 @@ export default async function VaChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/books/va/${slug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: "Vedānta-sūtra Transcript" })} />
<PageHeader sticky>
<Link
href="/books/va"
+3
View File
@@ -6,6 +6,8 @@ import { notFound } from "next/navigation";
import { getVaMeta } from "@/lib/va";
import { ogForBook } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { bookJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
export function generateMetadata(): Metadata {
@@ -18,6 +20,7 @@ export default async function VaPage() {
return (
<div className="min-h-screen bg-background">
<JsonLd data={bookJsonLd({ path: "/books/va", name: "Vedānta-sūtra Transcript" })} />
<PageHeader>
<Link
href="/books"
+3
View File
@@ -5,6 +5,8 @@ import Link from "next/link";
import { notFound } from "next/navigation";
import { ogForEssay, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -119,6 +121,7 @@ export default async function EssayPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/essays/${slug}`, headline: essay.title, description: essay.paragraphs?.[0], isPartOf: "Essays & Talks" })} />
<PageHeader sticky>
<Link
href="/essays"
+9
View File
@@ -5,6 +5,8 @@ import { notFound } from "next/navigation";
import { getAllGlossaryEntries } from "@/lib/api";
import { buildOgMeta, extractQuoteFromHl } from "@/lib/og";
import { GlossaryClient } from "../glossary-client";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
// ---------------------------------------------------------------------------
// Diacritic → base letter mapping
@@ -145,6 +147,13 @@ export default async function GlossaryLetterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd
data={articleJsonLd({
path: `/glossary/${rawLetter}`,
headline: `Glossary — ${activeLetter}`,
isPartOf: "Glossary of Sanskrit & Vedic Terms",
})}
/>
<GlossaryClient
entries={clientEntries}
activeLetter={activeLetter}
@@ -12,6 +12,8 @@ import {
} from "@/lib/journals";
import { ogForJournal, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -74,6 +76,7 @@ export default async function JournalChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/journals/${slug}/${chapterSlug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: meta.title })} />
<PageHeader sticky>
<Link
href={`/journals/${slug}`}
+11
View File
@@ -10,6 +10,8 @@ import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { cn } from "@/lib/utils";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
export async function generateMetadata({
params,
@@ -54,6 +56,15 @@ export default async function LetterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd
data={articleJsonLd({
path: `/letters/${slug}`,
headline: `Letter to ${letter.recipientDisplay}`,
description: letter.paragraphs[0],
datePublished: letter.year ? String(letter.year) : undefined,
isPartOf: "Letters of Śrīla Prabhupāda",
})}
/>
<PageHeader sticky>
<Link
href={backHref}
@@ -12,6 +12,8 @@ import {
} from "@/lib/magazines";
import { ogForMagazine, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -72,6 +74,7 @@ export default async function MagazineIssuePage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/magazines/${slug}/${issueSlug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: meta.title })} />
<PageHeader sticky>
<Link
href={`/magazines/${slug}`}
@@ -12,6 +12,8 @@ import {
} from "@/lib/other-documents";
import { ogForOtherDocument, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
import { PageHeader } from "@/components/layout/page-header";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
import { Card, CardContent } from "@/components/ui/card";
import { buttonVariants } from "@/components/ui/button";
import { ChevronLeft, ChevronRight } from "lucide-react";
@@ -79,6 +81,7 @@ export default async function OtherDocumentChapterPage({
return (
<div className="min-h-screen bg-background">
<JsonLd data={articleJsonLd({ path: `/other-documents/${slug}/${chapterSlug}`, headline: content.title, description: content.paragraphs?.[0], isPartOf: meta.title })} />
<PageHeader sticky>
<Link
href={`/other-documents/${slug}`}
+11
View File
@@ -16,6 +16,8 @@ import { cn } from "@/lib/utils";
import { ChevronLeft, ChevronRight, Clock, MapPin, Users } from "lucide-react";
import { PlayAudioButton } from "./play-audio-button";
import { FindInPage } from "@/components/layout/find-in-page";
import { JsonLd } from "@/components/seo/json-ld";
import { articleJsonLd } from "@/lib/jsonld";
export async function generateMetadata({
params,
@@ -82,6 +84,15 @@ export default async function TranscriptionPage({
return (
<div className="min-h-screen bg-background">
<JsonLd
data={articleJsonLd({
path: `/transcriptions/${slug}`,
headline: t.name,
description: t.content[0]?.text,
datePublished: t.year ? String(t.year) : undefined,
isPartOf: "Lectures & Conversations of Śrīla Prabhupāda",
})}
/>
<PageHeader sticky>
<Link
href={backHref}
+37 -6
View File
@@ -1,18 +1,23 @@
/**
* /u/[handle] — public profile, Posts tab (default).
*
* Server shell that exists for two reasons:
* Server shell that exists for three reasons:
*
* 1. Export `generateMetadata` so direct shares of this URL
* (https://prabhupadasays.org/u/<handle>) get a rich OG card
* pointing at /api/og/profile/<handle>. The layout and the body
* below are client components; only this file is server.
* 2. Mount the client tree (<PostsGrid />), which reads the
* ProfileContext provided by the parent layout for the post-grid
* hrefs and renders the feed.
* 2. Emit server-rendered ProfilePage/Person JSON-LD so crawlers + LLMs
* can resolve the profile (the layout is a client component and
* fetches the profile after hydration, too late for crawlers).
* 3. Mount the client tree (<PostsGrid />), which reads the
* ProfileContext provided by the parent layout.
*/
import type { Metadata } from "next";
import { bff } from "@/lib/bff";
import { JsonLd } from "@/components/seo/json-ld";
import { profileJsonLd } from "@/lib/jsonld";
import { PostsGrid } from "./posts-grid";
import { metadataForHandle } from "./profile-og";
@@ -23,6 +28,32 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
return metadataForHandle(handle);
}
export default function PublicProfilePage({ params }: Props) {
return <PostsGrid params={params} />;
export default async function PublicProfilePage({ params }: Props) {
const { handle } = await params;
let person: object | null = null;
try {
const profile = await bff<{
handle: string;
name: string;
avatar_url?: string | null;
}>(`/u/${encodeURIComponent(handle)}`, { revalidate: 60 });
if (profile) {
person = profileJsonLd({
path: `/u/${profile.handle}`,
name: profile.name,
handle: profile.handle,
image: profile.avatar_url ?? null,
});
}
} catch {
// Profile unavailable — skip JSON-LD rather than fail the page.
}
return (
<>
{person ? <JsonLd data={person} /> : null}
<PostsGrid params={params} />
</>
);
}
+28
View File
@@ -0,0 +1,28 @@
import { revalidateTag } from "next/cache";
import type { NextRequest } from "next/server";
/**
* On-demand cache revalidation. The BFF pings this (fire-and-forget) when
* sitemap-relevant data changes — a new signup, or a content re-seed/reindex —
* so /sitemap.xml refreshes within seconds instead of waiting out the 24h ISR
* window. Secret-gated; lives under /api/ which robots.txt disallows.
*
* POST /api/revalidate?tag=sitemap&secret=…
*/
export const runtime = "nodejs";
export async function POST(req: NextRequest) {
const expected = process.env.REVALIDATE_SECRET;
const secret = req.nextUrl.searchParams.get("secret");
if (!expected || secret !== expected) {
return Response.json(
{ revalidated: false, error: "unauthorized" },
{ status: 401 },
);
}
const tag = req.nextUrl.searchParams.get("tag") || "sitemap";
// Next 16 requires a cache-life profile as the 2nd arg; "max" fully purges
// the tagged entries so the next request re-fetches from the BFF.
revalidateTag(tag, "max");
return Response.json({ revalidated: true, tag });
}
+6
View File
@@ -43,6 +43,12 @@ const bricolage = Bricolage_Grotesque({
});
export const metadata: Metadata = {
// Resolves all relative OG/Twitter image URLs and canonical links to
// absolute URLs (required for correct social previews + SEO; Next warns
// without it).
metadataBase: new URL(
process.env.NEXT_PUBLIC_SITE_URL || "https://prabhupadasays.org",
),
title: "Prabhupāda Says",
description:
"Browse the books and teachings of His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda",
+45
View File
@@ -0,0 +1,45 @@
import type { MetadataRoute } from "next";
const SITE_URL =
process.env.NEXT_PUBLIC_SITE_URL || "https://prabhupadasays.org";
/**
* robots.txt (generated).
*
* Open the whole site to crawlers — search engines AND AI/LLM crawlers
* (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, etc. all honour the
* `*` rule, and we deliberately don't block them so the corpus is
* discoverable). Only private / non-content surfaces are disallowed:
*
* • /api/ — JSON endpoints, never a destination page
* • /settings — auth-only account settings
* • /notifications — auth-only
* • /verify-email — transactional
* • /chat — interactive tool, not indexable content
* • /u/me, /u/me/* — the signed-in user's own private library
* ($ anchors the bare path so public handles like
* /u/meera aren't caught by the prefix)
*
* Public content (books, verses, prose, letters, transcriptions, essays,
* disciples, magazines, journals, glossary, public profiles, collections)
* stays crawlable and is enumerated in the sitemap index.
*/
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: "*",
allow: "/",
disallow: [
"/api/",
"/settings",
"/notifications",
"/verify-email",
"/chat",
"/u/me$",
"/u/me/",
],
},
sitemap: `${SITE_URL}/sitemap.xml`,
host: SITE_URL,
};
}
+97
View File
@@ -0,0 +1,97 @@
import type { MetadataRoute } from "next";
import { bff } from "@/lib/bff";
/**
* Sitemap (index + sharded children) for the whole public corpus.
*
* How this stays cheap on the BFF:
* • One projection-only BFF call (`/sitemap/content`) returns every content
* leaf path in a single sweep — no per-document fan-out.
* • That fetch is cached for 24h (revalidate below) AND the rendered XML is
* ISR-cached, so crawlers hit Next's cache, not the BFF. The BFF sees
* ~one query/day regardless of crawl volume (tag "sitemap" allows
* on-demand revalidation after a re-seed).
* • generateSitemaps() shards into ≤40k-URL files (under the 50k/50MB
* limits) and Next serves a sitemap index at /sitemap.xml automatically.
*/
export const revalidate = 86400; // 24h
const SITE_URL =
process.env.NEXT_PUBLIC_SITE_URL || "https://prabhupadasays.org";
const PER_SITEMAP = 40000;
// Top-level hubs that aren't content leaves but should be indexed.
const STATIC_PATHS = [
"/",
"/about",
"/books",
"/letters",
"/transcriptions",
"/disciples",
"/glossary",
"/essays",
"/magazines",
"/journals",
"/other-documents",
];
/**
* All indexable paths: static hubs + book/division landing pages (derived
* from the content leaves) + every content leaf from the BFF. Resilient — if
* the BFF call fails we still emit the static hubs so /sitemap.xml never 500s.
*/
async function fetchUrls(path: string): Promise<string[]> {
try {
const res = await bff<{ urls: string[] }>(path, {
revalidate,
tags: ["sitemap"],
});
return res?.urls ?? [];
} catch {
return [];
}
}
async function allPaths(): Promise<string[]> {
// Content (Mongo) and public profiles (Postgres) come from separate
// projection-only endpoints. New signups appear automatically on the next
// daily revalidation.
const [content, users] = await Promise.all([
fetchUrls("/sitemap/content"),
fetchUrls("/sitemap/users"),
]);
// Derive non-redirecting hub pages from the content leaves: every book's
// landing page, and the SB canto / CC līlā division pages.
const hubs = new Set<string>();
for (const p of content) {
const book = p.match(/^\/books\/([^/]+)/);
if (book) hubs.add(`/books/${book[1]}`);
const division = p.match(/^\/books\/(sb|cc)\/([^/]+)\/\d+\/\d+$/);
if (division) hubs.add(`/books/${division[1]}/${division[2]}`);
}
// Dedupe across static + hubs + content + profiles.
return [...new Set([...STATIC_PATHS, ...hubs, ...content, ...users])];
}
export async function generateSitemaps(): Promise<{ id: number }[]> {
const paths = await allPaths();
const count = Math.max(1, Math.ceil(paths.length / PER_SITEMAP));
return Array.from({ length: count }, (_, id) => ({ id }));
}
export default async function sitemap({
id,
}: {
id: number;
}): Promise<MetadataRoute.Sitemap> {
const paths = await allPaths();
const slice = paths.slice(id * PER_SITEMAP, (id + 1) * PER_SITEMAP);
return slice.map((path) => ({
url: `${SITE_URL}${path}`,
changeFrequency: "weekly",
priority: path === "/" ? 1 : STATIC_PATHS.includes(path) ? 0.8 : 0.7,
}));
}
+14
View File
@@ -0,0 +1,14 @@
/**
* Renders a schema.org JSON-LD <script>. Safe in server or client components.
* The `<` escape prevents the JSON from breaking out of the <script> element.
*/
export function JsonLd({ data }: { data: object | object[] }) {
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(data).replace(/</g, "\\u003c"),
}}
/>
);
}
+121
View File
@@ -0,0 +1,121 @@
/**
* schema.org JSON-LD builders for content pages.
*
* Emitting structured data gives Google rich-result eligibility and gives
* LLMs clean, linked facts (who authored it, which work it belongs to, when).
* Every page renders one of these via the <JsonLd> component
* (components/seo/json-ld.tsx).
*
* The author entity carries `sameAs` links to Wikipedia/Wikidata so search
* engines and LLMs can resolve it to the canonical Śrīla Prabhupāda entity.
*/
const SITE_URL =
process.env.NEXT_PUBLIC_SITE_URL || "https://prabhupadasays.org";
const AUTHOR = {
"@type": "Person",
name: "His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda",
alternateName: "A.C. Bhaktivedanta Swami Prabhupāda",
sameAs: [
"https://en.wikipedia.org/wiki/A._C._Bhaktivedanta_Swami_Prabhupada",
"https://www.wikidata.org/wiki/Q318439",
],
} as const;
const PUBLISHER = {
"@type": "Organization",
name: "Prabhupāda Says",
url: SITE_URL,
} as const;
function abs(path: string): string {
return path.startsWith("http") ? path : `${SITE_URL}${path}`;
}
/** Trim a (possibly HTML) string to a clean plain-text description. */
function clean(text: string | undefined, max = 300): string | undefined {
if (!text) return undefined;
const plain = text
.replace(/<[^>]+>/g, "")
.replace(/\s+/g, " ")
.trim();
if (!plain) return undefined;
return plain.length > max ? plain.slice(0, max - 1).trimEnd() + "…" : plain;
}
/**
* An Article — used for every leaf content page (verses, letters, transcripts,
* prose chapters, essays, magazine/journal pages). `isPartOf` names the parent
* work (book/magazine); `datePublished` must be ISO 8601 (omit otherwise).
*/
export function articleJsonLd(params: {
path: string;
headline: string;
description?: string;
datePublished?: string;
isPartOf?: string;
}) {
const url = abs(params.path);
const obj: Record<string, unknown> = {
"@context": "https://schema.org",
"@type": "Article",
headline: params.headline,
author: AUTHOR,
publisher: PUBLISHER,
inLanguage: "en",
isAccessibleForFree: true,
url,
mainEntityOfPage: url,
};
const desc = clean(params.description);
if (desc) obj.description = desc;
if (params.datePublished) obj.datePublished = params.datePublished;
if (params.isPartOf) {
obj.isPartOf = { "@type": "Book", name: params.isPartOf, author: AUTHOR };
}
return obj;
}
/** A public profile page → ProfilePage wrapping the Person. */
export function profileJsonLd(params: {
path: string;
name: string;
handle: string;
image?: string | null;
}) {
const url = abs(params.path);
const person: Record<string, unknown> = {
"@type": "Person",
name: params.name,
alternateName: `@${params.handle}`,
url,
};
if (params.image) person.image = params.image;
return {
"@context": "https://schema.org",
"@type": "ProfilePage",
url,
mainEntity: person,
};
}
/** A Book — used for book landing pages. */
export function bookJsonLd(params: {
path: string;
name: string;
description?: string;
}) {
const obj: Record<string, unknown> = {
"@context": "https://schema.org",
"@type": "Book",
name: params.name,
author: AUTHOR,
publisher: PUBLISHER,
inLanguage: "en",
url: abs(params.path),
};
const desc = clean(params.description);
if (desc) obj.description = desc;
return obj;
}
+29
View File
@@ -0,0 +1,29 @@
# Prabhupāda Says
> The complete teachings of His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda — the books, lectures, conversations, and letters of the Founder-Ācārya of the International Society for Krishna Consciousness (ISKCON) — as structured, searchable, Unicode text (Devanāgarī + IAST transliteration).
All content is server-rendered and crawlable. The full URL list (tens of thousands of pages) is in the sitemap index.
## Sitemap
- [Sitemap index](https://prabhupadasays.org/sitemap.xml): every book, chapter, verse, prose chapter, letter, transcript, essay, magazine, and journal page
## Scriptures (books)
- [All books](https://prabhupadasays.org/books): Bhagavad-gītā As It Is, Śrīmad-Bhāgavatam, Śrī Caitanya-caritāmṛta, Nectar of Devotion, Kṛṣṇa Book, and 30+ more — browsable by chapter and verse (Devanāgarī, transliteration, synonyms, translation, and purport)
## Lectures & conversations
- [Transcriptions](https://prabhupadasays.org/transcriptions): ~3,800 lectures, morning walks, room conversations, and interviews (1966–1977), browsable by year, place, and type
## Letters
- [Letters](https://prabhupadasays.org/letters): ~6,900 letters (1947–1977), browsable by year, recipient, and location
## Reference
- [Glossary](https://prabhupadasays.org/glossary): ~2,750 Sanskrit/Vedic terms
- [Essays & other documents](https://prabhupadasays.org/essays)
- [Magazines (Back to Godhead)](https://prabhupadasays.org/magazines)
- [Journals](https://prabhupadasays.org/journals)
- [Disciples](https://prabhupadasays.org/disciples)
-2
View File
@@ -1,2 +0,0 @@
User-agent: *
Disallow: /