@@ -160,21 +160,36 @@ export async function generateSitePageMetadata(props: SitePageProps): Promise<Me
160160
161161 const canonical = (
162162 pageMetaLinks ?. canonical
163- ? new URL ( pageMetaLinks . canonical ) . toString ( )
163+ ? new URL (
164+ // If the canonical link is an absolute URL, use it as is.
165+ URL . canParse ( pageMetaLinks . canonical )
166+ ? pageMetaLinks . canonical
167+ : linker . toAbsoluteURL ( pageMetaLinks . canonical )
168+ ) . toString ( )
164169 : // If no canonical is set, use the current page URL (default case)
165170 linker . toAbsoluteURL ( linker . toPathForPage ( { pages : revision . pages , page } ) )
166171 ) . replace ( / \/ + $ / , '' ) ; // Trim trailing slashes in canonical URL to match the redirect behavior
167172
168- const languages = pageMetaLinks ?. alternates . reduce (
173+ const alternates = pageMetaLinks ?. alternates . reduce < {
174+ languages : Record < string , string > ;
175+ generic : Array < {
176+ title ?: string ;
177+ url : string ;
178+ } > ;
179+ } > (
169180 ( acc , alt ) => {
170- // TODO: We can only add language alternates for now as that's all Next.js API supports
171- // generic alternates are not supported yet
172181 if ( alt . space ?. language ) {
173- acc [ alt . space . language ] = alt . href ;
182+ acc . languages [ alt . space . language ] = URL . canParse ( alt . href )
183+ ? alt . href
184+ : linker . toAbsoluteURL ( alt . href ) ;
185+ } else {
186+ acc . generic . push ( {
187+ url : URL . canParse ( alt . href ) ? alt . href : linker . toAbsoluteURL ( alt . href ) ,
188+ } ) ;
174189 }
175190 return acc ;
176191 } ,
177- { } as Record < TranslationLanguage , string >
192+ { languages : { } , generic : [ ] }
178193 ) ;
179194
180195 return {
@@ -189,9 +204,13 @@ export async function generateSitePageMetadata(props: SitePageProps): Promise<Me
189204 description : page . description ?? '' ,
190205 alternates : {
191206 canonical,
192- languages,
207+ languages : alternates ?. languages ,
193208 types : {
194209 'text/markdown' : `${ linker . toAbsoluteURL ( linker . toPathInSpace ( page . path ) ) } .md` ,
210+ // Currently it will output with an empty "type" like <link rel="alternate" href="..." type />
211+ // Team at Vercel is aware of this and will ensure it will be omitted when the value is empty in future versions of Next.js
212+ // https://gitbook.slack.com/archives/C04K6MV5W1K/p1763034072958419?thread_ts=1762937203.511629&cid=C04K6MV5W1K
213+ ...( alternates ?. generic ? { '' : alternates ?. generic } : { } ) ,
195214 } ,
196215 } ,
197216 openGraph : {
0 commit comments