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.
This commit is contained in:
@@ -8,7 +8,7 @@ export async function generateMetadata({
|
||||
}: {
|
||||
params: { slug: string; lang: string };
|
||||
}): Promise<Metadata> {
|
||||
const post = await getPostBySlug(params.slug);
|
||||
const post = await getPostBySlug(params.slug, params.lang);
|
||||
|
||||
if (!post) {
|
||||
//blog not found
|
||||
|
||||
@@ -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 <div>Post not found</div>;
|
||||
|
||||
@@ -26,7 +26,7 @@ export default async function BlogPage({
|
||||
{/* Articles List */}
|
||||
<div className="space-y-12">
|
||||
{posts.map((post) => (
|
||||
<ArticleListItem key={post.slug} post={post} />
|
||||
<ArticleListItem key={post.slug} post={post} lang={lang} />
|
||||
))}
|
||||
</div>
|
||||
</main>
|
||||
@@ -41,7 +41,7 @@ export default async function BlogPage({
|
||||
{posts.slice(0, 5).map((post) => (
|
||||
<Link
|
||||
key={post.slug}
|
||||
href={`/en/blog/${post.slug}`}
|
||||
href={`/${lang}/blog/${post.slug}`}
|
||||
className="block hover:text-blue-600 text-base font-medium"
|
||||
>
|
||||
{post.frontmatter.title}
|
||||
|
||||
@@ -59,7 +59,7 @@ export default async function TagPage({
|
||||
<div className="space-y-12">
|
||||
{posts.length > 0 ? (
|
||||
posts.map((post) => (
|
||||
<ArticleListItem key={post.slug} post={post} />
|
||||
<ArticleListItem key={post.slug} post={post} lang={lang} />
|
||||
))
|
||||
) : (
|
||||
<p>No articles found for this decodedTag.</p>
|
||||
|
||||
@@ -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 (
|
||||
<article className="bg-white rounded-xl shadow-lg hover:shadow-xl transition-shadow overflow-hidden">
|
||||
<div className="relative h-80 w-full">
|
||||
@@ -37,7 +38,7 @@ export function ArticleListItem({ post }: ArticleListItemProps) {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Link href={`/blog/${post.slug}`}>
|
||||
<Link href={`/${lang}/blog/${post.slug}`}>
|
||||
<h2 className="text-3xl font-bold mb-4 hover:text-blue-600 transition-colors leading-tight">
|
||||
{post.frontmatter.title}
|
||||
</h2>
|
||||
@@ -49,7 +50,7 @@ export function ArticleListItem({ post }: ArticleListItemProps) {
|
||||
|
||||
<div className="flex items-center justify-between pt-4 border-t border-gray-100">
|
||||
<Link
|
||||
href={`/blog/${post.slug}`}
|
||||
href={`/${lang}/blog/${post.slug}`}
|
||||
className="text-blue-600 hover:text-blue-800 font-medium inline-flex items-center text-lg"
|
||||
>
|
||||
Read more
|
||||
|
||||
+41
-37
@@ -22,45 +22,45 @@ export interface BlogPost {
|
||||
export async function getAllPosts(lang: string): Promise<BlogPost[]> {
|
||||
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<BlogPost[]> {
|
||||
);
|
||||
}
|
||||
|
||||
export async function getPostBySlug(slug: string): Promise<BlogPost | null> {
|
||||
export async function getPostBySlug(
|
||||
slug: string,
|
||||
lang: string
|
||||
): Promise<BlogPost | null> {
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user