mirror of
https://github.com/kremalicious/blog.git
synced 2025-01-05 03:15:07 +01:00
SEO component
This commit is contained in:
parent
6c8dc9855f
commit
034eebc045
12
package.json
12
package.json
@ -27,10 +27,10 @@
|
|||||||
"dms2dec": "^1.1.0",
|
"dms2dec": "^1.1.0",
|
||||||
"fast-exif": "^1.0.1",
|
"fast-exif": "^1.0.1",
|
||||||
"fraction.js": "^4.0.9",
|
"fraction.js": "^4.0.9",
|
||||||
"gatsby": "^2.0.7",
|
"gatsby": "^2.0.8",
|
||||||
"gatsby-awesome-pagination": "^0.2.1",
|
"gatsby-awesome-pagination": "^0.2.1",
|
||||||
"gatsby-image": "^2.0.8",
|
"gatsby-image": "^2.0.9",
|
||||||
"gatsby-plugin-catch-links": "^2.0.2",
|
"gatsby-plugin-catch-links": "^2.0.3",
|
||||||
"gatsby-plugin-feed": "^2.0.5",
|
"gatsby-plugin-feed": "^2.0.5",
|
||||||
"gatsby-plugin-lunr": "^1.2.0",
|
"gatsby-plugin-lunr": "^1.2.0",
|
||||||
"gatsby-plugin-matomo": "^0.5.0",
|
"gatsby-plugin-matomo": "^0.5.0",
|
||||||
@ -43,12 +43,12 @@
|
|||||||
"gatsby-redirect-from": "^0.1.1",
|
"gatsby-redirect-from": "^0.1.1",
|
||||||
"gatsby-remark-autolink-headers": "^2.0.6",
|
"gatsby-remark-autolink-headers": "^2.0.6",
|
||||||
"gatsby-remark-copy-linked-files": "^2.0.5",
|
"gatsby-remark-copy-linked-files": "^2.0.5",
|
||||||
"gatsby-remark-images": "^2.0.1",
|
"gatsby-remark-images": "^2.0.2",
|
||||||
"gatsby-remark-prismjs": "^3.0.0",
|
"gatsby-remark-prismjs": "^3.0.0",
|
||||||
"gatsby-remark-smartypants": "^2.0.5",
|
"gatsby-remark-smartypants": "^2.0.5",
|
||||||
"gatsby-source-filesystem": "^2.0.1",
|
"gatsby-source-filesystem": "^2.0.1",
|
||||||
"gatsby-transformer-remark": "^2.1.3",
|
"gatsby-transformer-remark": "^2.1.3",
|
||||||
"gatsby-transformer-sharp": "^2.1.1",
|
"gatsby-transformer-sharp": "^2.1.2",
|
||||||
"gatsby-transformer-yaml": "^2.1.1",
|
"gatsby-transformer-yaml": "^2.1.1",
|
||||||
"graphql": "^0.13.2",
|
"graphql": "^0.13.2",
|
||||||
"intersection-observer": "^0.5.0",
|
"intersection-observer": "^0.5.0",
|
||||||
@ -84,7 +84,7 @@
|
|||||||
"stylelint": "^9.5.0",
|
"stylelint": "^9.5.0",
|
||||||
"stylelint-config-css-modules": "^1.3.0",
|
"stylelint-config-css-modules": "^1.3.0",
|
||||||
"stylelint-config-standard": "^18.2.0",
|
"stylelint-config-standard": "^18.2.0",
|
||||||
"stylelint-scss": "^3.3.0"
|
"stylelint-scss": "^3.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10.0.0"
|
"node": "^10.0.0"
|
||||||
|
145
src/components/atoms/SEO.jsx
Normal file
145
src/components/atoms/SEO.jsx
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { StaticQuery, graphql } from 'gatsby'
|
||||||
|
import Helmet from 'react-helmet'
|
||||||
|
|
||||||
|
const query = graphql`
|
||||||
|
query {
|
||||||
|
contentYaml {
|
||||||
|
title
|
||||||
|
tagline
|
||||||
|
url
|
||||||
|
author {
|
||||||
|
name
|
||||||
|
twitter
|
||||||
|
avatar {
|
||||||
|
childImageSharp {
|
||||||
|
resize(width: 160) {
|
||||||
|
src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
class SEO extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
post: PropTypes.object,
|
||||||
|
slug: PropTypes.string,
|
||||||
|
postSEO: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<StaticQuery
|
||||||
|
query={query}
|
||||||
|
render={data => {
|
||||||
|
const siteMeta = data.contentYaml
|
||||||
|
const { post, slug, postSEO } = this.props
|
||||||
|
let title
|
||||||
|
let description
|
||||||
|
let image
|
||||||
|
let postURL
|
||||||
|
|
||||||
|
if (postSEO) {
|
||||||
|
const postMeta = post.frontmatter
|
||||||
|
title = `${postMeta.title} ¦ ${siteMeta.tagline}`
|
||||||
|
description = postMeta.description
|
||||||
|
? postMeta.description
|
||||||
|
: post.excerpt
|
||||||
|
image = postMeta.image.childImageSharp.fluid.src
|
||||||
|
postURL = `${siteMeta.url}${slug}`
|
||||||
|
} else {
|
||||||
|
title = `${siteMeta.title} ¦ ${siteMeta.tagline}`
|
||||||
|
description = siteMeta.tagline
|
||||||
|
image = siteMeta.author.avatar.childImageSharp.resize.src
|
||||||
|
}
|
||||||
|
|
||||||
|
image = `${siteMeta.url}${image}`
|
||||||
|
const blogURL = siteMeta.url
|
||||||
|
const url = postSEO ? postURL : blogURL
|
||||||
|
|
||||||
|
const schemaOrgJSONLD = [
|
||||||
|
{
|
||||||
|
'@context': 'http://schema.org',
|
||||||
|
'@type': 'WebSite',
|
||||||
|
url: blogURL,
|
||||||
|
name: title,
|
||||||
|
alternateName: siteMeta.titleAlt ? siteMeta.titleAlt : ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
if (postSEO) {
|
||||||
|
schemaOrgJSONLD.push(
|
||||||
|
{
|
||||||
|
'@context': 'http://schema.org',
|
||||||
|
'@type': 'BreadcrumbList',
|
||||||
|
itemListElement: [
|
||||||
|
{
|
||||||
|
'@type': 'ListItem',
|
||||||
|
position: 1,
|
||||||
|
item: {
|
||||||
|
'@id': postURL,
|
||||||
|
name: title,
|
||||||
|
image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'@context': 'http://schema.org',
|
||||||
|
'@type': 'BlogPosting',
|
||||||
|
url: blogURL,
|
||||||
|
name: title,
|
||||||
|
alternateName: siteMeta.titleAlt ? siteMeta.titleAlt : '',
|
||||||
|
headline: title,
|
||||||
|
image: {
|
||||||
|
'@type': 'ImageObject',
|
||||||
|
url: image
|
||||||
|
},
|
||||||
|
description
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Helmet>
|
||||||
|
<html lang="en" />
|
||||||
|
|
||||||
|
{/* General tags */}
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
<meta name="image" content={image} />
|
||||||
|
<link rel="canonical" href={url} />
|
||||||
|
|
||||||
|
{/* Schema.org tags */}
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{JSON.stringify(schemaOrgJSONLD)}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{/* OpenGraph tags */}
|
||||||
|
<meta property="og:url" content={url} />
|
||||||
|
{postSEO && <meta property="og:type" content="article" />}
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
<meta property="og:image" content={image} />
|
||||||
|
|
||||||
|
{/* Twitter Card tags */}
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta
|
||||||
|
name="twitter:creator"
|
||||||
|
content={siteMeta.author.twitter ? siteMeta.author.twitter : ''}
|
||||||
|
/>
|
||||||
|
<meta name="twitter:title" content={title} />
|
||||||
|
<meta name="twitter:description" content={description} />
|
||||||
|
<meta name="twitter:image" content={image} />
|
||||||
|
</Helmet>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SEO
|
@ -8,6 +8,7 @@ import PostTitle from '../components/atoms/PostTitle'
|
|||||||
import PostLead from '../components/atoms/PostLead'
|
import PostLead from '../components/atoms/PostLead'
|
||||||
import PostContent from '../components/atoms/PostContent'
|
import PostContent from '../components/atoms/PostContent'
|
||||||
import PostActions from '../components/atoms/PostActions'
|
import PostActions from '../components/atoms/PostActions'
|
||||||
|
import SEO from '../components/atoms/SEO'
|
||||||
import PostMeta from '../components/molecules/PostMeta'
|
import PostMeta from '../components/molecules/PostMeta'
|
||||||
import Exif from '../components/atoms/Exif'
|
import Exif from '../components/atoms/Exif'
|
||||||
import styles from './Post.module.scss'
|
import styles from './Post.module.scss'
|
||||||
@ -16,6 +17,7 @@ const Post = ({ data, location }) => {
|
|||||||
const { markdownRemark: post } = data
|
const { markdownRemark: post } = data
|
||||||
const { contentYaml: meta } = data
|
const { contentYaml: meta } = data
|
||||||
const { title, image, type, linkurl, style } = post.frontmatter
|
const { title, image, type, linkurl, style } = post.frontmatter
|
||||||
|
const { slug } = post.fields
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout location={location}>
|
<Layout location={location}>
|
||||||
@ -23,19 +25,15 @@ const Post = ({ data, location }) => {
|
|||||||
{style && <link rel="stylesheet" href={style.publicURL} />}
|
{style && <link rel="stylesheet" href={style.publicURL} />}
|
||||||
</Helmet>
|
</Helmet>
|
||||||
|
|
||||||
|
<SEO slug={slug} post={post} postSEO />
|
||||||
|
|
||||||
<article className={styles.hentry}>
|
<article className={styles.hentry}>
|
||||||
<PostTitle type={type} linkurl={linkurl} title={title} />
|
<PostTitle type={type} linkurl={linkurl} title={title} />
|
||||||
|
|
||||||
<PostLead post={post} />
|
<PostLead post={post} />
|
||||||
|
|
||||||
{image && <PostImage fluid={image.childImageSharp.fluid} alt={title} />}
|
{image && <PostImage fluid={image.childImageSharp.fluid} alt={title} />}
|
||||||
|
|
||||||
{image && image.fields && <Exif exif={image.fields.exif} />}
|
{image && image.fields && <Exif exif={image.fields.exif} />}
|
||||||
|
|
||||||
<PostContent post={post} />
|
<PostContent post={post} />
|
||||||
|
<PostActions slug={slug} url={meta.url} />
|
||||||
<PostActions slug={post.fields.slug} url={meta.url} />
|
|
||||||
|
|
||||||
<PostMeta post={post} meta={meta} />
|
<PostMeta post={post} meta={meta} />
|
||||||
</article>
|
</article>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -8,6 +8,7 @@ import PostLead from '../components/atoms/PostLead'
|
|||||||
import PostContent from '../components/atoms/PostContent'
|
import PostContent from '../components/atoms/PostContent'
|
||||||
import PostMore from '../components/atoms/PostMore'
|
import PostMore from '../components/atoms/PostMore'
|
||||||
import PostLinkActions from '../components/atoms/PostLinkActions'
|
import PostLinkActions from '../components/atoms/PostLinkActions'
|
||||||
|
import SEO from '../components/atoms/SEO'
|
||||||
import Pagination from '../components/molecules/Pagination'
|
import Pagination from '../components/molecules/Pagination'
|
||||||
import Featured from '../components/molecules/Featured'
|
import Featured from '../components/molecules/Featured'
|
||||||
import styles from './Posts.module.scss'
|
import styles from './Posts.module.scss'
|
||||||
@ -54,6 +55,7 @@ const Posts = ({ data, location, pageContext }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout location={location}>
|
<Layout location={location}>
|
||||||
|
<SEO />
|
||||||
{location.pathname === '/' && <Featured />}
|
{location.pathname === '/' && <Featured />}
|
||||||
{tag && <h1 className={styles.archiveTitle}>{tag}</h1>}
|
{tag && <h1 className={styles.archiveTitle}>{tag}</h1>}
|
||||||
{previousPagePath && (
|
{previousPagePath && (
|
||||||
|
Loading…
Reference in New Issue
Block a user