Skip to content

Commit 6761dc4

Browse files
ericyangpanclaude
andcommitted
feat(search): improve metadata with language alternates
Enhance search page metadata generation with proper language alternates and canonical URLs using buildLanguageAlternates utility. This ensures better SEO and proper international indexing. Changes: - Use buildLanguageAlternates helper for consistent alternate links - Preserve query parameters in alternate language URLs - Clean up canonical URL generation - Remove hardcoded SITE_CONFIG.url usage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 56339a9 commit 6761dc4

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

src/app/[locale]/docs/[slug]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export default async function DocPage({ params }: Props) {
6969
This documentation page is coming soon. Check back later!
7070
</p>
7171
<Link
72-
href={`/${locale}/docs`}
72+
href="/docs"
7373
className="inline-flex items-center gap-[var(--spacing-xs)] text-sm text-[var(--color-text-secondary)] hover:text-[var(--color-text)] transition-colors mt-[var(--spacing-lg)]"
7474
>
7575
<span></span>

src/app/[locale]/search/page.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import type { Metadata } from 'next'
22
import { getTranslations } from 'next-intl/server'
33
import type { Locale } from '@/i18n/config'
4-
import { buildOpenGraph, buildTitle, buildTwitterCard, SITE_CONFIG } from '@/lib/metadata'
4+
import {
5+
buildLanguageAlternates,
6+
buildOpenGraph,
7+
buildTitle,
8+
buildTwitterCard,
9+
} from '@/lib/metadata'
510
import SearchPageClient from './page.client'
611

712
export const revalidate = 3600
@@ -18,7 +23,22 @@ export async function generateMetadata({ params, searchParams }: Props): Promise
1823

1924
const title = q ? t('resultsCountFor', { count: 0, query: q }) : t('title')
2025
const description = t('placeholder')
21-
const searchUrl = `/${locale}/search${q ? `?q=${encodeURIComponent(q)}` : ''}`
26+
27+
// Build canonical path based on locale (without query params for canonical)
28+
const canonicalPath = locale === 'en' ? '/search' : `/${locale}/search`
29+
30+
// Build query string if search query exists
31+
const queryString = q ? `?q=${encodeURIComponent(q)}` : ''
32+
33+
// Build full URL with query params for OpenGraph
34+
const searchUrl = `${canonicalPath}${queryString}`
35+
36+
// Build language alternates with query params
37+
const languageAlternates = buildLanguageAlternates('search')
38+
const alternatesWithQuery: Record<string, string> = {}
39+
Object.entries(languageAlternates).forEach(([lang, path]) => {
40+
alternatesWithQuery[lang] = `${path}${queryString}`
41+
})
2242

2343
return {
2444
title: buildTitle({ title }),
@@ -34,12 +54,8 @@ export async function generateMetadata({ params, searchParams }: Props): Promise
3454
description,
3555
}),
3656
alternates: {
37-
canonical: `${SITE_CONFIG.url}${searchUrl}`,
38-
languages: {
39-
en: `${SITE_CONFIG.url}/en/search${q ? `?q=${encodeURIComponent(q)}` : ''}`,
40-
'zh-Hans': `${SITE_CONFIG.url}/zh-Hans/search${q ? `?q=${encodeURIComponent(q)}` : ''}`,
41-
de: `${SITE_CONFIG.url}/de/search${q ? `?q=${encodeURIComponent(q)}` : ''}`,
42-
},
57+
canonical: canonicalPath,
58+
languages: alternatesWithQuery,
4359
},
4460
}
4561
}

0 commit comments

Comments
 (0)