feat: add metadata generation for post detail page and improve description formatting
This commit is contained in:
parent
118d994746
commit
be855563bb
2 changed files with 82 additions and 0 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { cookies, headers } from "next/headers";
|
import { cookies, headers } from "next/headers";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
|
import type { Metadata } from "next";
|
||||||
import Header from "@/components/header";
|
import Header from "@/components/header";
|
||||||
import DetailRawPanel from "@/components/detail-raw-panel";
|
import DetailRawPanel from "@/components/detail-raw-panel";
|
||||||
|
|
||||||
|
|
@ -20,6 +21,20 @@ type Me = {
|
||||||
role: "admin" | "writer" | "reader";
|
role: "admin" | "writer" | "reader";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getSourceLabel(type: SourceType) {
|
||||||
|
return type === "twitter" ? "X" : type === "pixiv" ? "Pixiv" : "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDetailDescription(post: PostDetailResponse) {
|
||||||
|
const author = post.author?.trim() || "unknown";
|
||||||
|
const source = getSourceLabel(post.type);
|
||||||
|
const tags = (post.tags ?? []).filter((tag) => tag.trim().length > 0).slice(0, 5);
|
||||||
|
const tagText = tags.length > 0 ? ` | Tags: ${tags.join(", ")}` : "";
|
||||||
|
return `${author} | ${source} post${tagText}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function getApiBaseUrl() {
|
async function getApiBaseUrl() {
|
||||||
const configuredBaseUrl = process.env.API_BASE_URL;
|
const configuredBaseUrl = process.env.API_BASE_URL;
|
||||||
if (configuredBaseUrl) {
|
if (configuredBaseUrl) {
|
||||||
|
|
@ -78,6 +93,71 @@ async function fetchViewerRole(apiBaseUrl: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
|
||||||
|
const { id } = await params;
|
||||||
|
const fallbackTitle = `Detail ${id} | Akiyama Mizuki`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const apiBaseUrl = await getApiBaseUrl();
|
||||||
|
const post = await fetchPostDetail(apiBaseUrl, id);
|
||||||
|
const detailUrl = `${apiBaseUrl}/detail/${id}`;
|
||||||
|
|
||||||
|
if (!post) {
|
||||||
|
return {
|
||||||
|
title: fallbackTitle,
|
||||||
|
description: "Post detail",
|
||||||
|
alternates: {
|
||||||
|
canonical: detailUrl,
|
||||||
|
},
|
||||||
|
robots: {
|
||||||
|
index: false,
|
||||||
|
follow: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = getSourceLabel(post.type);
|
||||||
|
const author = post.author?.trim() || "unknown";
|
||||||
|
const title = `${author} | ${source}`;
|
||||||
|
const description = createDetailDescription(post);
|
||||||
|
const ogImages = post.mediaUrl
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
url: post.mediaUrl,
|
||||||
|
alt: `${author} ${source}`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
alternates: {
|
||||||
|
canonical: detailUrl,
|
||||||
|
},
|
||||||
|
openGraph: {
|
||||||
|
type: "article",
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
url: detailUrl,
|
||||||
|
siteName: "Akiyama Mizuki",
|
||||||
|
images: ogImages,
|
||||||
|
},
|
||||||
|
twitter: {
|
||||||
|
card: post.mediaUrl ? "summary_large_image" : "summary",
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
images: post.mediaUrl ? [post.mediaUrl] : undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
title: fallbackTitle,
|
||||||
|
description: "Post detail",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default async function DetailPage({ params }: { params: Promise<{ id: string }> }) {
|
export default async function DetailPage({ params }: { params: Promise<{ id: string }> }) {
|
||||||
const { id } = await params;
|
const { id } = await params;
|
||||||
const apiBaseUrl = await getApiBaseUrl();
|
const apiBaseUrl = await getApiBaseUrl();
|
||||||
|
|
|
||||||
2
apps/frontend/src/app/robots.txt
Normal file
2
apps/frontend/src/app/robots.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
User-Agent: *
|
||||||
|
Disallow: /
|
||||||
Loading…
Add table
Add a link
Reference in a new issue