Fix tag URL encoding for non-ASCII characters
Fixed tag matching issue where tags with spaces and non-ASCII characters (like "Medicine - 醫學") were not working correctly on Vercel. Changes: 1. Updated getTagSlug() to normalize tags without encoding - Next.js handles URL encoding automatically 2. Added decodeURIComponent() in tag page to decode incoming URL parameters 3. This ensures proper matching between generated slugs and URL parameters The fix resolves: - Tag archive pages showing wrong characters - Articles not being collected under correct tags - URL display issues with encoded characters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -27,10 +27,12 @@ interface Props {
|
|||||||
|
|
||||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||||
const { tag: slug } = await params;
|
const { tag: slug } = await params;
|
||||||
|
// Decode the slug since Next.js encodes non-ASCII characters in URLs
|
||||||
|
const decodedSlug = decodeURIComponent(slug);
|
||||||
// Find original tag label by slug
|
// Find original tag label by slug
|
||||||
const tag = allPosts
|
const tag = allPosts
|
||||||
.flatMap((post) => post.tags ?? [])
|
.flatMap((post) => post.tags ?? [])
|
||||||
.find((t) => getTagSlug(t) === slug);
|
.find((t) => getTagSlug(t) === decodedSlug);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: tag ? `標籤:${tag}` : '標籤'
|
title: tag ? `標籤:${tag}` : '標籤'
|
||||||
@@ -39,13 +41,15 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|||||||
|
|
||||||
export default async function TagPage({ params }: Props) {
|
export default async function TagPage({ params }: Props) {
|
||||||
const { tag: slug } = await params;
|
const { tag: slug } = await params;
|
||||||
|
// Decode the slug since Next.js encodes non-ASCII characters in URLs
|
||||||
|
const decodedSlug = decodeURIComponent(slug);
|
||||||
|
|
||||||
const posts = allPosts.filter(
|
const posts = allPosts.filter(
|
||||||
(post) => post.tags && post.tags.some((t) => getTagSlug(t) === slug)
|
(post) => post.tags && post.tags.some((t) => getTagSlug(t) === decodedSlug)
|
||||||
);
|
);
|
||||||
|
|
||||||
const tagLabel =
|
const tagLabel =
|
||||||
posts[0]?.tags?.find((t) => getTagSlug(t) === slug) ?? slug;
|
posts[0]?.tags?.find((t) => getTagSlug(t) === decodedSlug) ?? decodedSlug;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarLayout>
|
<SidebarLayout>
|
||||||
|
|||||||
10
lib/posts.ts
10
lib/posts.ts
@@ -27,14 +27,14 @@ export function getPageBySlug(slug: string): Page | undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getTagSlug(tag: string): string {
|
export function getTagSlug(tag: string): string {
|
||||||
// Normalize spaces and convert to lowercase first
|
// Normalize spaces and convert to lowercase
|
||||||
// Replace multiple spaces/dashes with single dash
|
// Replace multiple spaces/dashes with single dash
|
||||||
const normalized = tag
|
// Next.js will handle URL encoding automatically, so we don't encode here
|
||||||
|
return tag
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.replace(/\s+/g, '-')
|
.replace(/\s+/g, '-')
|
||||||
.replace(/-+/g, '-');
|
.replace(/-+/g, '-')
|
||||||
// Encode URI components to handle non-ASCII characters properly
|
.trim();
|
||||||
return encodeURIComponent(normalized);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllTagsWithCount(): { tag: string; slug: string; count: number }[] {
|
export function getAllTagsWithCount(): { tag: string; slug: string; count: number }[] {
|
||||||
|
|||||||
Reference in New Issue
Block a user