@@ -10,7 +10,14 @@ import PropTypes from "prop-types";
10
10
import Helmet from "react-helmet" ;
11
11
import { useStaticQuery , graphql } from "gatsby" ;
12
12
13
- export function SEO ( { description, lang, meta, title } ) {
13
+ export function SEO ( {
14
+ description,
15
+ lang,
16
+ meta,
17
+ image : metaImage ,
18
+ title,
19
+ pathname
20
+ } ) {
14
21
const { site } = useStaticQuery (
15
22
graphql `
16
23
query {
@@ -19,13 +26,22 @@ export function SEO({ description, lang, meta, title }) {
19
26
title
20
27
description
21
28
author
29
+ keywords
30
+ siteUrl
31
+ social {
32
+ twitter
33
+ }
22
34
}
23
35
}
24
36
}
25
37
`
26
38
) ;
27
39
28
40
const metaDescription = description || site . siteMetadata . description ;
41
+ const image = metaImage ?. src
42
+ ? `${ site . siteMetadata . siteUrl } ${ metaImage . src } `
43
+ : null ;
44
+ const canonical = pathname ? `${ site . siteMetadata . siteUrl } ${ pathname } ` : null ;
29
45
30
46
return (
31
47
< Helmet
@@ -34,6 +50,16 @@ export function SEO({ description, lang, meta, title }) {
34
50
} }
35
51
title = { title }
36
52
titleTemplate = { `%s | ${ site . siteMetadata . title } ` }
53
+ link = {
54
+ canonical
55
+ ? [
56
+ {
57
+ rel : "canonical" ,
58
+ href : canonical
59
+ }
60
+ ]
61
+ : [ ]
62
+ }
37
63
meta = { [
38
64
{
39
65
name : `description` ,
@@ -43,6 +69,14 @@ export function SEO({ description, lang, meta, title }) {
43
69
property : `og:title` ,
44
70
content : title
45
71
} ,
72
+ {
73
+ name : "keywords" ,
74
+ content : site . siteMetadata . keywords . join ( "," )
75
+ } ,
76
+ {
77
+ property : `og:url` ,
78
+ content : site . siteMetadata . siteUrl
79
+ } ,
46
80
{
47
81
property : `og:description` ,
48
82
content : metaDescription
@@ -51,13 +85,9 @@ export function SEO({ description, lang, meta, title }) {
51
85
property : `og:type` ,
52
86
content : `website`
53
87
} ,
54
- {
55
- name : `twitter:card` ,
56
- content : `summary`
57
- } ,
58
88
{
59
89
name : `twitter:creator` ,
60
- content : site . siteMetadata . author
90
+ content : site . siteMetadata . social . twitter
61
91
} ,
62
92
{
63
93
name : `twitter:title` ,
@@ -67,7 +97,39 @@ export function SEO({ description, lang, meta, title }) {
67
97
name : `twitter:description` ,
68
98
content : metaDescription
69
99
}
70
- ] . concat ( meta ) }
100
+ ]
101
+ . concat (
102
+ metaImage
103
+ ? [
104
+ {
105
+ property : "og:image" ,
106
+ content : image
107
+ } ,
108
+ {
109
+ property : `og:image:alt` ,
110
+ content : title
111
+ } ,
112
+ {
113
+ property : "og:image:width" ,
114
+ content : metaImage . width
115
+ } ,
116
+ {
117
+ property : "og:image:height" ,
118
+ content : metaImage . height
119
+ } ,
120
+ {
121
+ name : "twitter:card" ,
122
+ content : "summary_large_image"
123
+ }
124
+ ]
125
+ : [
126
+ {
127
+ name : "twitter:card" ,
128
+ content : "summary"
129
+ }
130
+ ]
131
+ )
132
+ . concat ( meta ) }
71
133
/>
72
134
) ;
73
135
}
@@ -82,5 +144,11 @@ SEO.propTypes = {
82
144
description : PropTypes . string ,
83
145
lang : PropTypes . string ,
84
146
meta : PropTypes . arrayOf ( PropTypes . object ) ,
85
- title : PropTypes . string . isRequired
147
+ title : PropTypes . string . isRequired ,
148
+ image : PropTypes . shape ( {
149
+ src : PropTypes . string . isRequired ,
150
+ height : PropTypes . number . isRequired ,
151
+ width : PropTypes . number . isRequired
152
+ } ) ,
153
+ pathname : PropTypes . string
86
154
} ;
0 commit comments