Skip to content

Commit 7dbc59e

Browse files
authored
Merge pull request #133 from iterative/seo-component
2 parents ec9a925 + 91fa028 commit 7dbc59e

File tree

6 files changed

+130
-165
lines changed

6 files changed

+130
-165
lines changed

packages/gatsby-theme-iterative/gatsby-config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ module.exports = ({
158158
siteMetadata: {
159159
author: 'Iterative',
160160
titleTemplate: '',
161+
twitterUsername: '',
161162
plausibleSrc,
162163
plausibleAPI,
163164
plausibleDomain

packages/gatsby-theme-iterative/src/components/MainLayout/DefaultSEO/index.tsx

Lines changed: 0 additions & 142 deletions
This file was deleted.

packages/gatsby-theme-iterative/src/components/MainLayout/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import './fonts.css'
88
import LayoutHeader from '../LayoutHeader'
99
import LayoutFooter from '../LayoutFooter'
1010
import { handleFirstTab } from '../../utils/front/accessibility'
11-
import DefaultSEO from './DefaultSEO'
1211
import { useRedirects } from './utils'
12+
import SEO from '../SEO'
1313

1414
export enum LayoutModifiers {
1515
Wide,
@@ -54,7 +54,7 @@ const MainLayout = ({
5454
'items-center'
5555
)}
5656
>
57-
<DefaultSEO pathname={location.pathname} />
57+
<SEO pathname={location.pathname} />
5858
<LayoutHeader modifiers={modifiers} />
5959
<main
6060
className={cn(

packages/gatsby-theme-iterative/src/components/SEO/helper.ts

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { getSrc, IGatsbyImageData } from 'gatsby-plugin-image'
22

33
export type MetaProps = JSX.IntrinsicElements['meta']
4+
export type LinkProps = JSX.IntrinsicElements['link']
45

56
export const getMetaTitle = (title: string): MetaProps[] => {
67
return [
@@ -48,18 +49,52 @@ export const getMetaImage = (
4849
]
4950
}
5051

51-
export const buildMetadata = (
52-
siteUrl: string,
53-
title?: string,
54-
defaultMetaTitle?: boolean,
55-
description?: string,
56-
keywords?: string,
57-
image?: IGatsbyImageData | string,
58-
imageAlt?: string,
59-
imageHeight?: number,
52+
export const buildMetadata = ({
53+
siteUrl,
54+
siteName,
55+
title,
56+
defaultMetaTitle,
57+
description,
58+
keywords,
59+
image,
60+
imageAlt,
61+
imageHeight,
62+
imageWidth,
63+
pathname,
64+
twitterUsername
65+
}: {
66+
siteUrl: string
67+
siteName?: string
68+
title?: string
69+
defaultMetaTitle?: boolean
70+
description?: string
71+
keywords?: string
72+
image?: IGatsbyImageData | string
73+
imageAlt?: string
74+
imageHeight?: number
6075
imageWidth?: number
61-
) => {
62-
const prebuildMeta: MetaProps[] = []
76+
pathname?: string
77+
twitterUsername?: string
78+
}) => {
79+
const prebuildMeta: MetaProps[] = [
80+
{
81+
property: 'og:site_name',
82+
content: siteName
83+
},
84+
{
85+
property: 'og:type',
86+
content: 'website'
87+
},
88+
{
89+
property: 'og:locale',
90+
content: 'en_US'
91+
},
92+
{
93+
name: 'twitter:card',
94+
content: 'summary'
95+
}
96+
]
97+
6398
if (title && !defaultMetaTitle) {
6499
prebuildMeta.push(...getMetaTitle(title))
65100
}
@@ -83,5 +118,26 @@ export const buildMetadata = (
83118
...getMetaImage(imageUrl, imageAlt, imageHeight, imageWidth)
84119
)
85120
}
121+
if (pathname) {
122+
const fullUrl = siteUrl + pathname
123+
prebuildMeta.push({
124+
name: 'og:url',
125+
content: fullUrl
126+
})
127+
}
128+
if (twitterUsername) {
129+
prebuildMeta.push(
130+
...[
131+
{
132+
name: 'twitter:creator',
133+
content: twitterUsername
134+
},
135+
{
136+
name: 'twitter:site',
137+
content: twitterUsername
138+
}
139+
]
140+
)
141+
}
86142
return prebuildMeta
87143
}

packages/gatsby-theme-iterative/src/components/SEO/index.tsx

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Helmet from 'react-helmet'
33
import { IGatsbyImageData } from 'gatsby-plugin-image'
44

55
import getSiteMeta from '../../queries/siteMeta'
6-
import { buildMetadata, MetaProps } from './helper'
6+
import { buildMetadata, MetaProps, LinkProps } from './helper'
77

88
export interface IPaginatorPageInfo {
99
currentPage: number
@@ -22,6 +22,9 @@ interface ISEOProps {
2222
imageHeight?: number
2323
imageWidth?: number
2424
meta?: MetaProps[]
25+
link?: LinkProps[]
26+
canonicalUrl?: string
27+
pathname?: string
2528
pageInfo?: IPaginatorPageInfo
2629
children?: React.ReactNode
2730
}
@@ -32,32 +35,39 @@ const SEO: React.FC<ISEOProps> = ({
3235
skipTitleTemplate,
3336
description,
3437
keywords,
35-
image,
38+
image = '/social-share.png',
3639
imageAlt = '',
37-
imageHeight,
38-
imageWidth,
40+
imageHeight = 630,
41+
imageWidth = 1200,
3942
meta = [],
43+
link = [],
44+
canonicalUrl,
45+
pathname,
4046
pageInfo,
4147
children
4248
}) => {
4349
const siteMeta = getSiteMeta()
50+
const fullUrl = siteMeta.siteUrl + pathname
4451
const pageTitle = useMemo(() => {
4552
return pageInfo && pageInfo.currentPage > 1
4653
? `${title || siteMeta.title} page ${pageInfo.currentPage}`
4754
: title
4855
}, [title, siteMeta, pageInfo])
4956
const prebuildMeta = useMemo(() => {
50-
return buildMetadata(
51-
siteMeta.siteUrl,
52-
pageTitle,
57+
return buildMetadata({
58+
siteUrl: siteMeta.siteUrl,
59+
siteName: siteMeta.title,
60+
title: pageTitle,
5361
defaultMetaTitle,
5462
description,
5563
keywords,
5664
image,
5765
imageAlt,
5866
imageHeight,
59-
imageWidth
60-
)
67+
imageWidth,
68+
pathname,
69+
twitterUsername: siteMeta.twitterUsername
70+
})
6171
}, [
6272
siteMeta,
6373
pageTitle,
@@ -67,15 +77,53 @@ const SEO: React.FC<ISEOProps> = ({
6777
image,
6878
imageAlt,
6979
imageWidth,
70-
imageHeight
80+
imageHeight,
81+
pathname
7182
])
7283

7384
return (
7485
<Helmet
86+
htmlAttributes={{
87+
lang: 'en'
88+
}}
89+
defaultTitle={siteMeta.title}
7590
title={pageTitle}
91+
titleTemplate={
92+
skipTitleTemplate
93+
? ''
94+
: siteMeta.titleTemplate || `%s | ${siteMeta.title}`
95+
}
7696
{...(skipTitleTemplate && { titleTemplate: '' })}
7797
meta={[...prebuildMeta, ...meta]}
98+
link={[
99+
...(canonicalUrl
100+
? [
101+
{
102+
rel: 'canonical',
103+
href: canonicalUrl
104+
}
105+
]
106+
: pathname
107+
? [
108+
{
109+
rel: 'canonical',
110+
href: fullUrl
111+
}
112+
]
113+
: []),
114+
...link
115+
]}
78116
>
117+
{siteMeta.plausibleSrc ? (
118+
<script
119+
defer
120+
data-domain={
121+
siteMeta.plausibleDomain || new URL(siteMeta.siteUrl).hostname
122+
}
123+
data-api={siteMeta.plausibleAPI || undefined}
124+
src={siteMeta.plausibleSrc}
125+
/>
126+
) : null}
79127
{children}
80128
</Helmet>
81129
)

0 commit comments

Comments
 (0)