fix: use getTagSlug() for tag links to prevent empty tag pages
Tags containing both spaces and dashes (e.g. "Writings - 創作") produced mismatched slugs: inline generation created "writings---創作" while getTagSlug() collapsed dashes to "writings-創作", causing tag pages to show no articles. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -50,14 +50,19 @@ Ask the user if they want to preview with `npm run dev` before publishing.
|
||||
|
||||
## Step 5: Publish
|
||||
|
||||
Execute the two-step deployment:
|
||||
**IMPORTANT**: The `.gitmodules` URL for `content/` points to GitHub. The CI/CD server clones the submodule from that URL, so the content submodule **must be pushed to GitHub first** before pushing the main repo. Otherwise the server will check out stale content and posts will disappear from the site.
|
||||
|
||||
Execute the deployment in order:
|
||||
|
||||
```bash
|
||||
# 1. Commit and push content submodule
|
||||
git -C content add . && git -C content commit -m "Add new post: <title>" && git -C content push
|
||||
# 1. Commit content submodule
|
||||
git -C content add . && git -C content commit -m "Add new post: <title>"
|
||||
|
||||
# 2. Update main repo submodule pointer and push (triggers CI/CD)
|
||||
git add content && git commit -m "Update content submodule" && git push
|
||||
# 2. Push content submodule to ALL remotes (GitHub first — CI/CD depends on it)
|
||||
git -C content push github main && git -C content push origin main
|
||||
|
||||
# 3. Update main repo submodule pointer, commit, and push to both remotes
|
||||
git add content && git commit -m "Update content submodule" && git push origin main && git push github main
|
||||
```
|
||||
|
||||
Confirm both pushes succeeded. The CI/CD pipeline on git.gbanyan.net will handle deployment automatically (and crontab mirrors to gitea.gbanyan.net).
|
||||
Confirm all pushes succeeded. The CI/CD pipeline on git.gbanyan.net will handle deployment automatically (and crontab mirrors to gitea.gbanyan.net).
|
||||
|
||||
@@ -3,7 +3,7 @@ import Image from 'next/image';
|
||||
import { notFound } from 'next/navigation';
|
||||
import type { Metadata } from 'next';
|
||||
import { allPosts } from 'contentlayer2/generated';
|
||||
import { getPostBySlug, getRelatedPosts, getPostNeighbors } from '@/lib/posts';
|
||||
import { getPostBySlug, getRelatedPosts, getPostNeighbors, getTagSlug } from '@/lib/posts';
|
||||
import { siteConfig } from '@/lib/config';
|
||||
import { ReadingProgress } from '@/components/reading-progress';
|
||||
import { ScrollReveal } from '@/components/scroll-reveal';
|
||||
@@ -217,9 +217,7 @@ export default async function BlogPostPage({ params }: Props) {
|
||||
{post.tags.map((t) => (
|
||||
<Link
|
||||
key={t}
|
||||
href={`/tags/${encodeURIComponent(
|
||||
t.toLowerCase().replace(/\s+/g, '-')
|
||||
)}`}
|
||||
href={`/tags/${encodeURIComponent(getTagSlug(t))}`}
|
||||
className="tag-chip rounded-full bg-accent-soft px-3 py-1 text-sm text-accent-textLight dark:bg-slate-800 dark:text-slate-100 dark:hover:bg-slate-700 dark:hover:text-white"
|
||||
>
|
||||
#{t}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Image from 'next/image';
|
||||
import { notFound } from 'next/navigation';
|
||||
import type { Metadata } from 'next';
|
||||
import { allPages } from 'contentlayer2/generated';
|
||||
import { getPageBySlug } from '@/lib/posts';
|
||||
import { getPageBySlug, getTagSlug } from '@/lib/posts';
|
||||
import { siteConfig } from '@/lib/config';
|
||||
import { ReadingProgress } from '@/components/reading-progress';
|
||||
import { PostLayout } from '@/components/post-layout';
|
||||
@@ -130,9 +130,7 @@ export default async function StaticPage({ params }: Props) {
|
||||
{page.tags.map((t) => (
|
||||
<Link
|
||||
key={t}
|
||||
href={`/tags/${encodeURIComponent(
|
||||
t.toLowerCase().replace(/\s+/g, '-')
|
||||
)}`}
|
||||
href={`/tags/${encodeURIComponent(getTagSlug(t))}`}
|
||||
className="tag-chip rounded-full bg-accent-soft px-3 py-1 text-sm text-accent-textLight dark:bg-slate-800 dark:text-slate-100"
|
||||
>
|
||||
#{t}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
import { allPosts, allPages } from 'contentlayer2/generated';
|
||||
import { getTagSlug } from '@/lib/posts';
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000';
|
||||
@@ -58,7 +59,7 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||
);
|
||||
|
||||
const tagPages = allTags.map((tag) => ({
|
||||
url: `${siteUrl}/tags/${encodeURIComponent(tag.toLowerCase().replace(/\s+/g, '-'))}`,
|
||||
url: `${siteUrl}/tags/${encodeURIComponent(getTagSlug(tag))}`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'weekly' as const,
|
||||
priority: 0.5,
|
||||
|
||||
2
next-env.d.ts
vendored
2
next-env.d.ts
vendored
@@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/dev/types/routes.d.ts";
|
||||
import "./.next/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
||||
Reference in New Issue
Block a user