5
5
import * as React from 'react' ;
6
6
import Head from 'next/head' ;
7
7
import { withRouter , Router } from 'next/router' ;
8
+ import { siteConfig } from '../siteConfig' ;
8
9
9
10
export interface SeoProps {
10
11
title : string ;
@@ -16,6 +17,16 @@ export interface SeoProps {
16
17
searchOrder ?: number ;
17
18
}
18
19
20
+ const deployedTranslations = [
21
+ 'en' ,
22
+ // We'll add more languages when they have enough content.
23
+ ] ;
24
+
25
+ function getDomain ( languageCode : string ) : string {
26
+ const subdomain = languageCode === 'en' ? '' : languageCode + '.' ;
27
+ return subdomain + 'react.dev' ;
28
+ }
29
+
19
30
export const Seo = withRouter (
20
31
( {
21
32
title,
@@ -26,29 +37,37 @@ export const Seo = withRouter(
26
37
isHomePage,
27
38
searchOrder,
28
39
} : SeoProps & { router : Router } ) => {
40
+ const siteDomain = getDomain ( siteConfig . languageCode ) ;
41
+ const canonicalUrl = `https://${ siteDomain } ${
42
+ router . asPath . split ( / [ \? \# ] / ) [ 0 ]
43
+ } `;
29
44
const pageTitle = isHomePage ? 'React' : title + ' – React' ;
30
45
// Twitter's meta parser is not very good.
31
46
const twitterTitle = pageTitle . replace ( / [ < > ] / g, '' ) ;
32
47
return (
33
48
< Head >
34
- { /* DEFAULT */ }
35
-
36
49
< meta name = "viewport" content = "width=device-width, initial-scale=1" />
37
-
38
50
{ title != null && < title key = "title" > { pageTitle } </ title > }
39
51
{ description != null && (
40
52
< meta name = "description" key = "description" content = { description } />
41
53
) }
42
- { /* <link rel="icon" type="image/x-icon" href={favicon} />
43
- <link rel="apple-touch-icon" href={favicon} /> @todo favicon */ }
54
+ < link rel = "canonical" href = { canonicalUrl } />
55
+ < link
56
+ rel = "alternate"
57
+ href = { canonicalUrl . replace ( siteDomain , getDomain ( 'en' ) ) }
58
+ hrefLang = "x-default"
59
+ />
60
+ { deployedTranslations . map ( ( languageCode ) => (
61
+ < link
62
+ key = { 'alt-' + languageCode }
63
+ rel = "alternate"
64
+ hrefLang = { languageCode }
65
+ href = { canonicalUrl . replace ( siteDomain , getDomain ( languageCode ) ) }
66
+ />
67
+ ) ) }
44
68
< meta property = "fb:app_id" content = "623268441017527" />
45
- { /* OPEN GRAPH */ }
46
69
< meta property = "og:type" key = "og:type" content = "website" />
47
- < meta
48
- property = "og:url"
49
- key = "og:url"
50
- content = { `https://react.dev${ router . asPath . split ( / [ \? \# ] / ) [ 0 ] } ` }
51
- />
70
+ < meta property = "og:url" key = "og:url" content = { canonicalUrl } />
52
71
{ title != null && (
53
72
< meta property = "og:title" content = { pageTitle } key = "og:title" />
54
73
) }
@@ -59,14 +78,11 @@ export const Seo = withRouter(
59
78
content = { description }
60
79
/>
61
80
) }
62
-
63
81
< meta
64
82
property = "og:image"
65
83
key = "og:image"
66
- content = { `https://react.dev ${ image } ` }
84
+ content = { `https://${ siteDomain } ${ image } ` }
67
85
/>
68
-
69
- { /* TWITTER */ }
70
86
< meta
71
87
name = "twitter:card"
72
88
key = "twitter:card"
@@ -88,11 +104,10 @@ export const Seo = withRouter(
88
104
content = { description }
89
105
/>
90
106
) }
91
-
92
107
< meta
93
108
name = "twitter:image"
94
109
key = "twitter:image"
95
- content = { `https://react.dev ${ image } ` }
110
+ content = { `https://${ siteDomain } ${ image } ` }
96
111
/>
97
112
< meta
98
113
name = "google-site-verification"
0 commit comments