Skip to content

Commit

Permalink
SEO Implementation
Browse files Browse the repository at this point in the history
Consolidated most meta tags to the SEO component
Includes squashed pt-pt3 commits from other PR
  • Loading branch information
brandonkal committed May 10, 2018
1 parent d08f574 commit c40a71e
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 45 deletions.
150 changes: 150 additions & 0 deletions src/components/SEO.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React, { Component } from 'react'
import Helmet from 'react-helmet'
import config from '../utils/siteConfig'

class SEO extends Component {
render() {
const { postNode, pagePath, postSEO, pageSEO } = this.props
let title
let description
let image
let imgWidth
let imgHeight
let pageUrl

// Set Default OpenGraph Parameters for Fallback
title = config.siteTitle
description = config.siteDescription
image = config.siteUrl + config.siteLogo
imgWidth = 512
imgHeight = 512
pageUrl = config.siteUrl

// Replace with Page Parameters if post or page
if (postSEO || pageSEO) {
title = postNode.title
description =
postNode.metaDescription === null
? postNode.body.childMarkdownRemark.excerpt
: postNode.metaDescription

pageUrl = config.siteUrl + '/' + pagePath + '/'
}
// Use Hero Image for OpenGraph
if (postSEO) {
image = 'https:' + postNode.heroImage.ogimg.src
imgWidth = postNode.heroImage.ogimg.width
imgHeight = postNode.heroImage.ogimg.height
}

// Default Website Schema
const schemaOrgJSONLD = [
{
'@context': 'http://schema.org',
'@type': 'WebSite',
url: config.siteUrl,
name: config.siteTitle,
alternateName: config.siteTitleAlt ? config.siteTitleAlt : '',
},
]

// Blog Post Schema
if (postSEO) {
schemaOrgJSONLD.push(
{
'@context': 'http://schema.org',
'@type': 'BreadcrumbList',
itemListElement: [
{
'@type': 'ListItem',
position: 1,
item: {
'@id': config.siteUrl,
name: config.siteTitle,
},
},
{
'@type': 'ListItem',
position: 2,
item: {
'@id': pageUrl,
name: title,
},
},
],
},
{
'@context': 'http://schema.org',
'@type': 'BlogPosting',
url: pageUrl,
name: title,
alternateName: config.siteTitleAlt ? config.siteTitleAlt : '',
headline: title,
image: {
'@type': 'ImageObject',
url: image,
width: imgWidth,
height: imgHeight,
},
author: {
'@type': 'Person',
name: config.author,
url: config.authorUrl,
},
publisher: {
'@type': 'Organization',
name: config.publisher,
url: config.siteUrl,
},
datePublished: postNode.publishDateISO,
mainEntityOfPage: pageUrl,
}
)
}

// Page SEO Schema
if (pageSEO) {
schemaOrgJSONLD.push({
'@context': 'http://schema.org',
'@type': 'WebPage',
url: pageUrl,
name: title,
})
}

return (
<Helmet>
{/* General tags */}
<meta name="image" content={image} />
<meta name="description" content={description} />

{/* Schema.org tags */}
<script type="application/ld+json">
{JSON.stringify(schemaOrgJSONLD)}
</script>

{/* OpenGraph tags */}
<meta property="og:title" content={title} />
{postSEO ? <meta property="og:type" content="article" /> : null}

<meta property="og:url" content={pageUrl} />
<meta property="og:image" content={image} />
<meta property="og:image:width" content={imgWidth} />
<meta property="og:image:height" content={imgHeight} />
<meta property="og:description" content={description} />

{/* Twitter Card tags */}
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:creator"
content={config.userTwitter ? config.userTwitter : ''}
/>
<meta name="twitter:title" content={title} />
<meta name="twitter:image" content={image} />
<meta name="twitter:description" content={description} />
</Helmet>
)
}
}

export default SEO
2 changes: 1 addition & 1 deletion src/layouts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ const Template = ({ children }) => {
<link rel="icon" href={favicon} />
<meta name="description" content={config.siteDescription} />
<meta property="og:title" content={config.siteTitle} />
<meta property="og:url" content={config.siteUrl} />
<meta property="og:locale" content="en_US" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content={config.siteTitle} />
<meta property="og:url" content={config.siteUrl} />
</Helmet>

<ThemeProvider theme={theme}>
Expand Down
1 change: 1 addition & 0 deletions src/pages/404.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const NotFoundPage = () => (
<div>
<Helmet>
<title>404 - Page Not Found</title>
<meta name="description" content="Page not found" />
</Helmet>

<Box>
Expand Down
82 changes: 43 additions & 39 deletions src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,54 @@ import CardList from '../components/CardList'
import Card from '../components/Card'
import Container from '../components/Container'
import PageTitle from '../components/PageTitle'
import SEO from '../components/SEO'

const Index = ({ data }) => {
const posts = data.allContentfulPost.edges

return (
<Container>
<PageTitle small>
<a
href="https://www.gatsbyjs.org/"
target="_blank"
rel="noopener noreferrer"
>
Gatsby
</a>,{' '}
<a
href="https://www.contentful.com/"
target="_blank"
rel="noopener noreferrer"
>
Contentful
</a>{' '}
and{' '}
<a
href="https://www.netlify.com/"
target="_blank"
rel="noopener noreferrer"
>
Netlify
</a>{' '}
<span>🎉</span>
</PageTitle>
<CardList>
{posts.map(({ node: post }) => (
<Card
key={post.id}
slug={post.slug}
image={post.heroImage}
title={post.title}
date={post.publishDate}
excerpt={post.body}
/>
))}
</CardList>
</Container>
<div>
<SEO />
<Container>
<PageTitle small>
<a
href="https://www.gatsbyjs.org/"
target="_blank"
rel="noopener noreferrer"
>
Gatsby
</a>,{' '}
<a
href="https://www.contentful.com/"
target="_blank"
rel="noopener noreferrer"
>
Contentful
</a>{' '}
and{' '}
<a
href="https://www.netlify.com/"
target="_blank"
rel="noopener noreferrer"
>
Netlify
</a>{' '}
<span>🎉</span>
</PageTitle>
<CardList>
{posts.map(({ node: post }) => (
<Card
key={post.id}
slug={post.slug}
image={post.heroImage}
title={post.title}
date={post.publishDate}
excerpt={post.body}
/>
))}
</CardList>
</Container>
</div>
)
}

Expand Down
7 changes: 5 additions & 2 deletions src/templates/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import config from '../utils/siteConfig'
import Container from '../components/Container'
import PageTitle from '../components/PageTitle'
import PageBody from '../components/PageBody'
import SEO from '../components/SEO'

const PageTemplate = ({ data }) => {
const { title, slug, body } = data.contentfulPage
const postNode = data.contentfulPage

return (
<div>
<Helmet>
<title>{`${title} - ${config.siteTitle}`}</title>
<meta property="og:title" content={`${title} - ${config.siteTitle}`} />
<meta property="og:url" content={`${config.siteUrl}/${slug}/`} />
</Helmet>
<SEO pagePath={slug} postNode={postNode} pageSEO />

<Container>
<PageTitle>{title}</PageTitle>
Expand All @@ -29,9 +30,11 @@ export const query = graphql`
contentfulPage(slug: { eq: $slug }) {
title
slug
metaDescription
body {
childMarkdownRemark {
html
excerpt(pruneLength: 130)
}
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/templates/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import PageBody from '../components/PageBody'
import TagList from '../components/TagList'
import PostLinks from '../components/PostLinks'
import PostDate from '../components/PostDate'
import SEO from '../components/SEO'

const PostTemplate = ({ data }) => {
const {
Expand All @@ -19,6 +20,7 @@ const PostTemplate = ({ data }) => {
publishDate,
tags,
} = data.contentfulPost
const postNode = data.contentfulPost

const postIndex = find(
data.allContentfulPost.edges,
Expand All @@ -29,10 +31,8 @@ const PostTemplate = ({ data }) => {
<div>
<Helmet>
<title>{`${title} - ${config.siteTitle}`}</title>
<meta property="og:title" content={`${title} - ${config.siteTitle}`} />
<meta property="og:url" content={`${config.siteUrl}/${slug}/`} />
<meta property="og:image" content={heroImage.sizes.src} />
</Helmet>
<SEO pagePath={slug} postNode={postNode} postSEO />

<Hero title={title} image={heroImage} height={'50vh'} />

Expand All @@ -52,7 +52,9 @@ export const query = graphql`
title
id
slug
metaDescription
publishDate(formatString: "MMMM DD, YYYY")
publishDateISO: publishDate(formatString: "YYYY-MM-DD")
tags {
title
id
Expand All @@ -63,10 +65,16 @@ export const query = graphql`
sizes(maxWidth: 1800) {
...GatsbyContentfulSizes_withWebp_noBase64
}
ogimg: resize(width: 1800) {
src
width
height
}
}
body {
childMarkdownRemark {
html
excerpt(pruneLength: 130)
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/utils/siteConfig.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
module.exports = {
siteTitle: 'GCN',
siteTitleAlt: 'GCN Gatsby Starter', // This allows an alternative site title for SEO schema.
publisher: 'Publisher named GCN', // Organization name used for SEO schema
siteDescription:
'A starter template to build amazing static websites with Gatsby, Contentful and Netlify',
siteUrl: 'https://gcn.netlify.com', // Site domain. Do not include a trailing slash! If you wish to use a path prefix you can read more about that here: https://www.gatsbyjs.org/docs/path-prefix/

author: 'GCN User', // Author for RSS author segment and SEO schema
authorUrl: 'https://gcn.netlify.com/about/', // URL used for author and publisher schema, can be a social profile or other personal site
userTwitter: '@twitter', // Change for Twitter Cards

// Open Graph Default Share Image 1200x1200 is recommended
shortTitle: 'GCN App', // Used for App manifest e.g. Mobile Home Screen
shareImage: '/logos/share.jpg',
shareImageWidth: 900,
shareImageHeight: 600,

siteLogo: '/logos/logo-512.png', // Logo used for SEO, RSS, and App manifest
backgroundColor: '#e9e9e9', // Used for Offline Manifest
themeColor: '#121212', // Used for Offline Manifest
Expand Down
Binary file added static/logos/share.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c40a71e

Please sign in to comment.