From 245c4efcd0131459af1eb31e3f46969aa289d9df Mon Sep 17 00:00:00 2001 From: david_bai Date: Sat, 2 Aug 2025 23:27:02 +0800 Subject: [PATCH] fix(blog url bug): fix blog url bug Fixed the bug of redundant language suffix in blog URLs, added lang to the blog homepage link to prevent language switching issues. --- frontend/app/[lang]/blog/[slug]/metadata.ts | 2 +- frontend/app/[lang]/blog/[slug]/page.tsx | 4 +- frontend/app/[lang]/blog/page.tsx | 4 +- frontend/app/[lang]/blog/tag/[tag]/page.tsx | 2 +- frontend/components/blog/ArticleListItem.tsx | 7 +- frontend/lib/blog.ts | 78 ++++++++++---------- 6 files changed, 51 insertions(+), 46 deletions(-) diff --git a/frontend/app/[lang]/blog/[slug]/metadata.ts b/frontend/app/[lang]/blog/[slug]/metadata.ts index cac3ed9..f6ac71e 100644 --- a/frontend/app/[lang]/blog/[slug]/metadata.ts +++ b/frontend/app/[lang]/blog/[slug]/metadata.ts @@ -8,7 +8,7 @@ export async function generateMetadata({ }: { params: { slug: string; lang: string }; }): Promise { - const post = await getPostBySlug(params.slug); + const post = await getPostBySlug(params.slug, params.lang); if (!post) { //blog not found diff --git a/frontend/app/[lang]/blog/[slug]/page.tsx b/frontend/app/[lang]/blog/[slug]/page.tsx index aaa174a..9e6a6a7 100644 --- a/frontend/app/[lang]/blog/[slug]/page.tsx +++ b/frontend/app/[lang]/blog/[slug]/page.tsx @@ -12,9 +12,9 @@ export { generateMetadata }; export default async function BlogPost({ params, }: { - params: { slug: string }; + params: { slug: string; lang: string }; }) { - const post = await getPostBySlug(params.slug); + const post = await getPostBySlug(params.slug, params.lang); if (!post) { return
Post not found
; diff --git a/frontend/app/[lang]/blog/page.tsx b/frontend/app/[lang]/blog/page.tsx index 6ff2b9a..f4a8081 100644 --- a/frontend/app/[lang]/blog/page.tsx +++ b/frontend/app/[lang]/blog/page.tsx @@ -26,7 +26,7 @@ export default async function BlogPage({ {/* Articles List */}
{posts.map((post) => ( - + ))}
@@ -41,7 +41,7 @@ export default async function BlogPage({ {posts.slice(0, 5).map((post) => ( {post.frontmatter.title} diff --git a/frontend/app/[lang]/blog/tag/[tag]/page.tsx b/frontend/app/[lang]/blog/tag/[tag]/page.tsx index 63515bd..43fba35 100644 --- a/frontend/app/[lang]/blog/tag/[tag]/page.tsx +++ b/frontend/app/[lang]/blog/tag/[tag]/page.tsx @@ -59,7 +59,7 @@ export default async function TagPage({
{posts.length > 0 ? ( posts.map((post) => ( - + )) ) : (

No articles found for this decodedTag.

diff --git a/frontend/components/blog/ArticleListItem.tsx b/frontend/components/blog/ArticleListItem.tsx index 073b917..db7bab2 100644 --- a/frontend/components/blog/ArticleListItem.tsx +++ b/frontend/components/blog/ArticleListItem.tsx @@ -4,9 +4,10 @@ import { type BlogPost } from "@/lib/blog"; interface ArticleListItemProps { post: BlogPost; + lang: string; } -export function ArticleListItem({ post }: ArticleListItemProps) { +export function ArticleListItem({ post, lang }: ArticleListItemProps) { return (
@@ -37,7 +38,7 @@ export function ArticleListItem({ post }: ArticleListItemProps) { ))}
- +

{post.frontmatter.title}

@@ -49,7 +50,7 @@ export function ArticleListItem({ post }: ArticleListItemProps) {
Read more diff --git a/frontend/lib/blog.ts b/frontend/lib/blog.ts index eddefa7..5439362 100644 --- a/frontend/lib/blog.ts +++ b/frontend/lib/blog.ts @@ -22,45 +22,45 @@ export interface BlogPost { export async function getAllPosts(lang: string): Promise { const files = fs.readdirSync(POSTS_PATH); - const posts = await Promise.all( - files - .filter((file) => /\.mdx?$/.test(file)) - .map(async (file) => { - const filePath = path.join(POSTS_PATH, file); - const source = fs.readFileSync(filePath, "utf8"); - const { data, content } = matter(source); + const postsWithLang = files + .filter((file) => /\.mdx?$/.test(file)) + .map((file) => { + const langFromFile = file.match(/-([a-z]{2})\.mdx?$/)?.[1]; + return { file, langFromFile }; + }); - // Validate and transform frontmatter data - const frontmatter = { - title: data.title ?? "", - description: data.description ?? "", - date: data.date ?? new Date().toISOString(), - author: data.author ?? "", - cover: data.cover ?? "", - tags: Array.isArray(data.tags) ? data.tags : [], // Use the tags array directly - status: data.status ?? "draft", - }; - - return { - slug: file.replace(/\.mdx?$/, ""), - frontmatter, - content, - } as BlogPost; - }) + const lang_dst = lang === "zh" ? "zh" : "en"; + const filteredFiles = postsWithLang.filter( + ({ langFromFile }) => langFromFile === lang_dst ); - // Filter out draft status blogs - return posts - .filter((post) => post.frontmatter.status === "published") // Only keep published status - .filter((post) => { - // Split slug into an array by '-' - const parts = post.slug.split("-"); - // Get the last part - const lastPart = parts[parts.length - 1]; - // Check if the last part equals the target language && if the target language is Chinese, return Chinese blogs, otherwise return English blogs - const lang_dst = lang === "zh" ? "zh" : "en"; - return lastPart === lang_dst; + const posts = await Promise.all( + filteredFiles.map(async ({ file }) => { + const filePath = path.join(POSTS_PATH, file); + const source = fs.readFileSync(filePath, "utf8"); + const { data, content } = matter(source); + + // Validate and transform frontmatter data + const frontmatter = { + title: data.title ?? "", + description: data.description ?? "", + date: data.date ?? new Date().toISOString(), + author: data.author ?? "", + cover: data.cover ?? "", + tags: Array.isArray(data.tags) ? data.tags : [], + status: data.status ?? "draft", + }; + + return { + slug: file.replace(/-[a-z]{2}\.mdx?$/, "").replace(/\.mdx?$/, ""), + frontmatter, + content, + } as BlogPost; }) + ); + + return posts + .filter((post) => post.frontmatter.status === "published") .sort( (a, b) => new Date(b.frontmatter.date).getTime() - @@ -68,9 +68,13 @@ export async function getAllPosts(lang: string): Promise { ); } -export async function getPostBySlug(slug: string): Promise { +export async function getPostBySlug( + slug: string, + lang: string +): Promise { try { - const filePath = path.join(POSTS_PATH, `${slug}.mdx`); + const lang_dst = lang === "zh" ? "zh" : "en"; + const filePath = path.join(POSTS_PATH, `${slug}-${lang_dst}.mdx`); const source = fs.readFileSync(filePath, "utf8"); const { data, content } = matter(source);