feat: re-enable blog post metadata and CodeBlock component

This commit is contained in:
Mauricio Siu
2025-03-02 21:22:14 -06:00
parent c9d02a98d4
commit 26cad40c68
3 changed files with 301 additions and 312 deletions

View File

@@ -14,7 +14,7 @@ import type { BundledLanguage } from "shiki/bundle/web";
import TurndownService from "turndown"; import TurndownService from "turndown";
// @ts-ignore // @ts-ignore
import * as turndownPluginGfm from "turndown-plugin-gfm"; import * as turndownPluginGfm from "turndown-plugin-gfm";
// import { CodeBlock } from "./components/CodeBlock"; import { CodeBlock } from "./components/CodeBlock";
import { H1, H2, H3 } from "./components/Headings"; import { H1, H2, H3 } from "./components/Headings";
import { TableOfContents } from "./components/TableOfContents"; import { TableOfContents } from "./components/TableOfContents";
import { ZoomableImage } from "./components/ZoomableImage"; import { ZoomableImage } from "./components/ZoomableImage";
@@ -22,50 +22,50 @@ type Props = {
params: { locale: string; slug: string }; params: { locale: string; slug: string };
}; };
// export async function generateMetadata( export async function generateMetadata(
// { params }: Props, { params }: Props,
// parent: ResolvingMetadata, parent: ResolvingMetadata,
// ): Promise<Metadata> { ): Promise<Metadata> {
// const { locale, slug } = await params; const { locale, slug } = await params;
// const post = await getPost(slug); const post = await getPost(slug);
// if (!post) { if (!post) {
// return { return {
// title: "Post Not Found", title: "Post Not Found",
// }; };
// } }
// const ogUrl = new URL( const ogUrl = new URL(
// `/${locale}/api/og`, `/${locale}/api/og`,
// process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000", process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000",
// ); );
// ogUrl.searchParams.set("slug", slug); ogUrl.searchParams.set("slug", slug);
// return { return {
// title: post.title, title: post.title,
// description: post.custom_excerpt || post.excerpt, description: post.custom_excerpt || post.excerpt,
// openGraph: { openGraph: {
// title: post.title, title: post.title,
// description: post.custom_excerpt || post.excerpt, description: post.custom_excerpt || post.excerpt,
// type: "article", type: "article",
// url: `${process.env.NEXT_PUBLIC_APP_URL}/blog/${post.slug}`, url: `${process.env.NEXT_PUBLIC_APP_URL}/blog/${post.slug}`,
// images: [ images: [
// { {
// url: ogUrl.toString(), url: ogUrl.toString(),
// width: 1200, width: 1200,
// height: 630, height: 630,
// alt: post.title, alt: post.title,
// }, },
// ], ],
// }, },
// twitter: { twitter: {
// card: "summary_large_image", card: "summary_large_image",
// title: post.title, title: post.title,
// description: post.custom_excerpt || post.excerpt, description: post.custom_excerpt || post.excerpt,
// images: [ogUrl.toString()], images: [ogUrl.toString()],
// }, },
// }; };
// } }
export async function generateStaticParams() { export async function generateStaticParams() {
const posts = await getPosts(); const posts = await getPosts();
@@ -80,10 +80,9 @@ export async function generateStaticParams() {
} }
export default async function BlogPostPage({ params }: Props) { export default async function BlogPostPage({ params }: Props) {
try { const { slug } = await params;
const { locale, slug } = await params;
// setRequestLocale(locale); // setRequestLocale(locale);
const t = await getTranslations({ locale, namespace: "blog" }); const t = await getTranslations("blog");
const post = await getPost(slug); const post = await getPost(slug);
const allPosts = await getPosts(); const allPosts = await getPosts();
@@ -106,14 +105,11 @@ export default async function BlogPostPage({ params }: Props) {
const markdown = turndownService.turndown(post.html); const markdown = turndownService.turndown(post.html);
const formattedDate = new Date(post.published_at).toLocaleDateString( const formattedDate = new Date(post.published_at).toLocaleDateString("en", {
locale,
{
year: "numeric", year: "numeric",
month: "long", month: "long",
day: "numeric", day: "numeric",
}, });
);
const components: Partial<Components> = { const components: Partial<Components> = {
h1: H1, h1: H1,
@@ -178,15 +174,15 @@ export default async function BlogPostPage({ params }: Props) {
className="object-cover max-w-lg mx-auto rounded-lg border max-lg:w-64 border-border overflow-hidden" className="object-cover max-w-lg mx-auto rounded-lg border max-lg:w-64 border-border overflow-hidden"
/> />
), ),
// code: ({ className, children }) => { code: ({ className, children }) => {
// const match = /language-(\w+)/.exec(className || ""); const match = /language-(\w+)/.exec(className || "");
// return ( return (
// <CodeBlock <CodeBlock
// lang={match ? (match[1] as BundledLanguage) : "ts"} lang={match ? (match[1] as BundledLanguage) : "ts"}
// code={children?.toString() || ""} code={children?.toString() || ""}
// /> />
// ); );
// }, },
}; };
return ( return (
@@ -319,7 +315,7 @@ export default async function BlogPostPage({ params }: Props) {
{relatedPosts.map((relatedPost) => { {relatedPosts.map((relatedPost) => {
const relatedPostDate = new Date( const relatedPostDate = new Date(
relatedPost.published_at, relatedPost.published_at,
).toLocaleDateString(locale, { ).toLocaleDateString("en", {
year: "numeric", year: "numeric",
month: "long", month: "long",
day: "numeric", day: "numeric",
@@ -347,8 +343,7 @@ export default async function BlogPostPage({ params }: Props) {
{relatedPost.title} {relatedPost.title}
</h3> </h3>
<p className="text-sm text-muted-foreground mb-4"> <p className="text-sm text-muted-foreground mb-4">
{relatedPostDate} {relatedPost.reading_time} min {relatedPostDate} {relatedPost.reading_time} min read
read
</p> </p>
<p className="text-muted-foreground line-clamp-2"> <p className="text-muted-foreground line-clamp-2">
{relatedPost.excerpt} {relatedPost.excerpt}
@@ -363,8 +358,4 @@ export default async function BlogPostPage({ params }: Props) {
)} )}
</article> </article>
); );
} catch (error) {
console.error("Error in BlogPostPage:", error);
return <div>Error loading blog post</div>;
}
} }

View File

@@ -2,11 +2,10 @@ import { getPosts, getTags } from "@/lib/ghost";
import type { Post } from "@/lib/ghost"; import type { Post } from "@/lib/ghost";
import { RssIcon } from "lucide-react"; import { RssIcon } from "lucide-react";
import type { Metadata } from "next"; import type { Metadata } from "next";
import { getTranslations, setRequestLocale } from "next-intl/server"; import { getTranslations } from "next-intl/server";
import Link from "next/link"; import Link from "next/link";
import { BlogPostCard } from "./components/BlogPostCard"; import { BlogPostCard } from "./components/BlogPostCard";
import { SearchAndFilter } from "./components/SearchAndFilter"; import { SearchAndFilter } from "./components/SearchAndFilter";
interface Tag { interface Tag {
id: string; id: string;
name: string; name: string;
@@ -27,8 +26,7 @@ export default async function BlogPage({
}) { }) {
const { locale } = await params; const { locale } = await params;
const searchParams2 = await searchParams; const searchParams2 = await searchParams;
setRequestLocale(locale); const t = await getTranslations("blog");
const t = await getTranslations({ locale, namespace: "blog" });
const posts = await getPosts(); const posts = await getPosts();
const tags = (await getTags()) as Tag[]; const tags = (await getTags()) as Tag[];
const search = const search =

View File

@@ -11,8 +11,8 @@ type Props = {
}; };
export async function generateMetadata({ params }: Props): Promise<Metadata> { export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { tag, locale } = params; const { tag } = await params;
const t = await getTranslations({ locale, namespace: "blog" }); const t = await getTranslations("blog");
return { return {
title: `${t("tagTitle", { tag })}`, title: `${t("tagTitle", { tag })}`,
@@ -29,8 +29,8 @@ export async function generateStaticParams() {
} }
export default async function TagPage({ params }: Props) { export default async function TagPage({ params }: Props) {
const { locale, tag } = params; const { tag } = await params;
const t = await getTranslations({ locale, namespace: "blog" }); const t = await getTranslations("blog");
const posts = await getPostsByTag(tag); const posts = await getPostsByTag(tag);
if (!posts || posts.length === 0) { if (!posts || posts.length === 0) {