feat(frontend): rich OG metadata + dynamic page titles across all routes
Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Has been cancelled
test / unit (pull_request) Has been cancelled
test / integration (pull_request) Has been cancelled
Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Has been cancelled
test / unit (pull_request) Has been cancelled
test / integration (pull_request) Has been cancelled
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { cookies } from "next/headers";
|
||||
import {
|
||||
getThoughtById,
|
||||
getThoughtThread,
|
||||
getUserProfile,
|
||||
getMe,
|
||||
@@ -14,6 +16,42 @@ interface ThoughtPageProps {
|
||||
params: Promise<{ thoughtId: string }>;
|
||||
}
|
||||
|
||||
function stripHtml(html: string) {
|
||||
return html.replace(/<[^>]*>/g, "").trim();
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: ThoughtPageProps): Promise<Metadata> {
|
||||
const { thoughtId } = await params;
|
||||
const thought = await getThoughtById(thoughtId, null).catch(() => null);
|
||||
if (!thought) return { title: "Thought" };
|
||||
|
||||
const author = thought.author.displayName || thought.author.username;
|
||||
const preview = stripHtml(thought.content).slice(0, 120);
|
||||
const description = preview || `A thought by ${author}`;
|
||||
|
||||
return {
|
||||
title: `${author}: "${preview.slice(0, 60)}${preview.length > 60 ? "…" : ""}"`,
|
||||
description,
|
||||
openGraph: {
|
||||
type: "article",
|
||||
title: `${author} on Thoughts`,
|
||||
description,
|
||||
images: thought.author.avatarUrl
|
||||
? [{ url: thought.author.avatarUrl }]
|
||||
: [],
|
||||
publishedTime: thought.createdAt.toISOString(),
|
||||
},
|
||||
twitter: {
|
||||
card: "summary",
|
||||
title: `${author} on Thoughts`,
|
||||
description,
|
||||
images: thought.author.avatarUrl ? [thought.author.avatarUrl] : [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function collectAuthors(thread: ThoughtThreadType): string[] {
|
||||
const authors = new Set<string>([thread.author.username]);
|
||||
for (const reply of thread.replies) {
|
||||
|
||||
Reference in New Issue
Block a user