@@ -22,8 +22,7 @@ interface PageProps {
2222export async function generateMetadata ( {
2323 params,
2424} : PageProps ) : Promise < Metadata > {
25- const { platform, pattern } = await params ;
26-
25+ const { platform, category, pattern } = await params ;
2726 const patternName = slugToPattern ( pattern ) ;
2827 const platformName = platform === "web" ? "Web" : "Mobile" ;
2928
@@ -32,12 +31,27 @@ export async function generateMetadata({
3231 absolute : `${ patternName } Pattern for ${ platformName } | UX Patterns Gallery` ,
3332 } ,
3433 description : `Examples and best practices for ${ patternName . toLowerCase ( ) } in ${ platformName . toLowerCase ( ) } applications.` ,
34+ alternates : {
35+ canonical : `${ process . env . NEXT_PUBLIC_SITE_URL } /${ platform } /${ category } /${ pattern } ` ,
36+ } ,
37+ openGraph : {
38+ title : `${ patternName } Pattern for ${ platformName } | UX Patterns Gallery` ,
39+ description : `Examples and best practices for ${ patternName . toLowerCase ( ) } in ${ platformName . toLowerCase ( ) } applications.` ,
40+ url : `${ process . env . NEXT_PUBLIC_SITE_URL } /${ platform } /${ category } /${ pattern } ` ,
41+ type : "article" ,
42+ } ,
43+ twitter : {
44+ card : "summary_large_image" ,
45+ title : `${ patternName } Pattern for ${ platformName } | UX Patterns Gallery` ,
46+ description : `Examples and best practices for ${ patternName . toLowerCase ( ) } in ${ platformName . toLowerCase ( ) } applications.` ,
47+ } ,
48+ robots : { index : true , follow : true } ,
3549 } ;
3650}
3751
3852export default async function PatternPage ( { params, searchParams } : PageProps ) {
3953 const { platform, category, pattern } = await params ;
40- const searchParamsResolved = await searchParams ;
54+ const searchParamsResolved = ( await searchParams ) ?? { } ;
4155
4256 if ( ! [ "web" , "mobile" ] . includes ( platform ) ) notFound ( ) ;
4357 if ( ! isCategorySlug ( category ) ) notFound ( ) ;
@@ -48,7 +62,19 @@ export default async function PatternPage({ params, searchParams }: PageProps) {
4862
4963 const filters = parseUrlToFilters (
5064 `/${ platform } /${ category } /${ pattern } ` ,
51- new URLSearchParams ( searchParamsResolved as any ) ,
65+ ( ( ) => {
66+ const p = new URLSearchParams ( ) ;
67+ for ( const [ k , v ] of Object . entries ( searchParamsResolved ?? { } ) ) {
68+ if ( Array . isArray ( v ) ) {
69+ for ( const vv of v ) {
70+ p . append ( k , vv ) ;
71+ }
72+ } else if ( typeof v === "string" ) {
73+ p . set ( k , v ) ;
74+ }
75+ }
76+ return p ;
77+ } ) ( ) ,
5278 ) ;
5379
5480 const entries = await loadEntries ( ) ;
@@ -72,9 +98,9 @@ export default async function PatternPage({ params, searchParams }: PageProps) {
7298 const patternName = slugToPattern ( pattern ) ;
7399 const categoryName = slugToPattern ( category ) ;
74100
75- // Count do's and don'ts
76- const _doCount = patternEntries . filter ( ( e ) => e . type === "do" ) . length ;
77- const _dontCount = patternEntries . filter ( ( e ) => e . type === "dont" ) . length ;
101+ // (optional) Add a small summary badge using these counts, or remove them if not needed.
102+ // const doCount = patternEntries.filter((e) => e.type === "do").length;
103+ // const dontCount = patternEntries.filter((e) => e.type === "dont").length;
78104
79105 return (
80106 < div className = "min-h-screen" >
@@ -101,15 +127,17 @@ export default async function PatternPage({ params, searchParams }: PageProps) {
101127 Examples and best practices for { patternName . toLowerCase ( ) } in{ " " }
102128 { platform } applications
103129 </ p >
104- < a
105- href = { `${ process . env . NEXT_PUBLIC_DOCS_URL } /patterns/${ category } /${ pattern } ` }
106- target = "_blank"
107- rel = "noopener noreferrer"
108- className = "inline-flex items-center gap-2 px-4 py-2 mt-4 bg-fd-card text-fd-foreground rounded-lg text-sm font-medium shadow-sm hover:bg-fd-muted focus:outline-none focus:ring-2 focus:ring-fd-primary transition-all border border-fd-border"
109- >
110- View Pattern
111- < ExternalLink className = "w-4 h-4" />
112- </ a >
130+ { process . env . NEXT_PUBLIC_DOCS_URL ? (
131+ < a
132+ href = { `${ process . env . NEXT_PUBLIC_DOCS_URL } /patterns/${ category } /${ pattern } ` }
133+ target = "_blank"
134+ rel = "noopener noreferrer"
135+ className = "inline-flex items-center gap-2 px-4 py-2 mt-4 bg-fd-card text-fd-foreground rounded-lg text-sm font-medium shadow-sm hover:bg-fd-muted focus:outline-none focus:ring-2 focus:ring-fd-primary transition-all border border-fd-border"
136+ >
137+ View Pattern
138+ < ExternalLink className = "w-4 h-4" />
139+ </ a >
140+ ) : null }
113141 </ div >
114142 </ div >
115143
0 commit comments