Stable image URLs (post-signing removal) make page-level caching safe again. Homepage, genre page, sitemap, and detail page now revalidate on an interval instead of running Prisma on every hit. Reader and search keep dynamic rendering (searchParams) but wrap their Prisma queries in unstable_cache. TTLs: home/genre/detail 5m, reader manga 5m, reader page meta 1h (immutable), search 1m, sitemap 1h. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
47 lines
1.1 KiB
TypeScript
47 lines
1.1 KiB
TypeScript
import { unstable_cache } from "next/cache";
|
|
import { prisma } from "@/lib/db";
|
|
import { MangaGrid } from "@/components/MangaGrid";
|
|
import type { Metadata } from "next";
|
|
|
|
export const metadata: Metadata = {
|
|
title: "Search",
|
|
};
|
|
|
|
type Props = {
|
|
searchParams: Promise<{ q?: string }>;
|
|
};
|
|
|
|
const searchManga = unstable_cache(
|
|
async (q: string) =>
|
|
prisma.manga.findMany({
|
|
where: {
|
|
status: "PUBLISHED",
|
|
title: { contains: q, mode: "insensitive" },
|
|
},
|
|
orderBy: { title: "asc" },
|
|
include: { _count: { select: { chapters: true } } },
|
|
}),
|
|
["search-manga"],
|
|
{ revalidate: 60 }
|
|
);
|
|
|
|
export default async function SearchPage({ searchParams }: Props) {
|
|
const { q } = await searchParams;
|
|
const manga = q ? await searchManga(q) : [];
|
|
|
|
return (
|
|
<div className="max-w-7xl mx-auto px-4 py-6">
|
|
<h1 className="text-xl font-bold mb-4">
|
|
{q ? `Results for "${q}"` : "Search"}
|
|
</h1>
|
|
{q ? (
|
|
<MangaGrid manga={manga} />
|
|
) : (
|
|
<p className="text-muted text-center py-12">
|
|
Use the search bar above to find manga
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|