Skip to content

Commit b19defc

Browse files
author
Muguku
committed
add social media banner image and handle, SEO keywords and canonical link
1 parent 228829b commit b19defc

File tree

3 files changed

+126
-13
lines changed

3 files changed

+126
-13
lines changed

gatsby-config.js

+35-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,41 @@ module.exports = {
77
title: `Muguku`,
88
owner: `Macharia Muguku`,
99
description: `A Macharia Muguku software engineer portfolio website`,
10-
author: `Macharia Muguku <[email protected]>`
10+
author: `Macharia Muguku <[email protected]>`,
11+
// don't use trailing slash
12+
siteUrl: "http://muguku.co.ke",
13+
social: {
14+
twitter: "@charmgk"
15+
},
16+
keywords: [
17+
"macharia muguku",
18+
"macharia",
19+
"muguku",
20+
"software engineer",
21+
"full-stack developer",
22+
"software",
23+
"engineer",
24+
"developer",
25+
"fullstack",
26+
"front-end",
27+
"frontend",
28+
"minimalist",
29+
"gatsby",
30+
"portfolio",
31+
"react",
32+
"reactjs",
33+
"react.js",
34+
"node",
35+
"nodejs",
36+
"node.js",
37+
"golang",
38+
"go",
39+
"docker",
40+
"react",
41+
"nginx",
42+
"graphql",
43+
"mpesa"
44+
]
1145
},
1246
plugins: [
1347
`gatsby-transformer-sharp`,

src/components/homeLayout.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -222,23 +222,34 @@ export const HomeLayout = () => {
222222
// check if media is mobile
223223
const isMobileOrTablet = useMediaQuery("(max-width: 48rem)");
224224

225-
// query for side data
225+
// query for site data and optimized SEO image
226226
const {
227-
site: { siteMetadata }
227+
site: { siteMetadata },
228+
SeoImage
228229
} = useStaticQuery(graphql`
229-
query SiteTitleQuery {
230+
query SiteTitleQueryAndSeoImage {
230231
site {
231232
siteMetadata {
232233
title
233234
owner
234235
}
235236
}
237+
SeoImage: file(relativePath: { eq: "screenshot.png" }) {
238+
childImageSharp {
239+
fixed(width: 1280, height: 640) {
240+
...GatsbyImageSharpFixed
241+
}
242+
}
243+
}
236244
}
237245
`);
238246

239247
return (
240248
<VerticalContainer>
241-
<SEO title={activeMenuAndComponent.Menu} />
249+
<SEO
250+
title={activeMenuAndComponent.Menu}
251+
image={SeoImage.childImageSharp.fixed}
252+
/>
242253
<Header
243254
siteTitle={siteMetadata.title}
244255
scrollToTop={scrollToTop}

src/components/seo.js

+76-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ import PropTypes from "prop-types";
1010
import Helmet from "react-helmet";
1111
import { useStaticQuery, graphql } from "gatsby";
1212

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+
}) {
1421
const { site } = useStaticQuery(
1522
graphql`
1623
query {
@@ -19,13 +26,22 @@ export function SEO({ description, lang, meta, title }) {
1926
title
2027
description
2128
author
29+
keywords
30+
siteUrl
31+
social {
32+
twitter
33+
}
2234
}
2335
}
2436
}
2537
`
2638
);
2739

2840
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;
2945

3046
return (
3147
<Helmet
@@ -34,6 +50,16 @@ export function SEO({ description, lang, meta, title }) {
3450
}}
3551
title={title}
3652
titleTemplate={`%s | ${site.siteMetadata.title}`}
53+
link={
54+
canonical
55+
? [
56+
{
57+
rel: "canonical",
58+
href: canonical
59+
}
60+
]
61+
: []
62+
}
3763
meta={[
3864
{
3965
name: `description`,
@@ -43,6 +69,14 @@ export function SEO({ description, lang, meta, title }) {
4369
property: `og:title`,
4470
content: title
4571
},
72+
{
73+
name: "keywords",
74+
content: site.siteMetadata.keywords.join(",")
75+
},
76+
{
77+
property: `og:url`,
78+
content: site.siteMetadata.siteUrl
79+
},
4680
{
4781
property: `og:description`,
4882
content: metaDescription
@@ -51,13 +85,9 @@ export function SEO({ description, lang, meta, title }) {
5185
property: `og:type`,
5286
content: `website`
5387
},
54-
{
55-
name: `twitter:card`,
56-
content: `summary`
57-
},
5888
{
5989
name: `twitter:creator`,
60-
content: site.siteMetadata.author
90+
content: site.siteMetadata.social.twitter
6191
},
6292
{
6393
name: `twitter:title`,
@@ -67,7 +97,39 @@ export function SEO({ description, lang, meta, title }) {
6797
name: `twitter:description`,
6898
content: metaDescription
6999
}
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)}
71133
/>
72134
);
73135
}
@@ -82,5 +144,11 @@ SEO.propTypes = {
82144
description: PropTypes.string,
83145
lang: PropTypes.string,
84146
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
86154
};

0 commit comments

Comments
 (0)