1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-12-22 17:23:50 +01:00

Merge pull request #202 from kremalicious/feature/seo

feature/seo
This commit is contained in:
Matthias Kretschmann 2019-11-25 23:32:45 +01:00 committed by GitHub
commit ad02ab3f7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 199 additions and 171 deletions

View File

@ -1,171 +0,0 @@
import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import { Helmet } from 'react-helmet'
import { useSiteMetadata } from '../../hooks/use-site-metadata'
import { Post } from '../../@types/Post'
const query = graphql`
query {
logo: allFile(filter: { name: { eq: "apple-touch-icon" } }) {
edges {
node {
relativePath
}
}
}
}
`
// const createSchemaOrg = (
// blogURL: string,
// title: string,
// postSEO: boolean,
// postURL: string,
// image: string,
// description: string,
// author?: string
// ) => {
// const schemaOrgJSONLD: any = [
// {
// '@context': 'http://schema.org',
// '@type': 'WebSite',
// url: blogURL,
// name: title
// }
// ]
// if (postSEO) {
// schemaOrgJSONLD.push({
// '@context': 'http://schema.org',
// '@type': 'BlogPosting',
// author,
// publisher: author,
// url: postURL,
// name: title,
// headline: title,
// image: {
// '@type': 'ImageObject',
// url: image
// },
// description
// })
// }
// return schemaOrgJSONLD
// }
const MetaTags = ({
description,
image,
url,
// schema,
postSEO,
title
}: {
description: string
image: string
url: string
// schema: string
postSEO: boolean
title: string
}) => {
const { siteTitle, siteDescription, siteUrl, author } = useSiteMetadata()
return (
<Helmet
defaultTitle={`${siteTitle} ¦ ${siteDescription}`}
titleTemplate={`%s ¦ ${siteTitle}`}
>
<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">{schema}</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={author.twitter ? author.twitter : ''}
/>
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={image} />
<link
rel="alternate"
title="JSON Feed"
type="application/json"
href={`${siteUrl}/feed.json`}
/>
</Helmet>
)
}
export default function SEO({
post,
slug,
postSEO
}: {
post?: Post
slug?: string
postSEO?: boolean
}) {
const data = useStaticQuery(query)
const logo = data.logo.edges[0].node.relativePath
const { siteTitle, siteUrl, siteDescription } = useSiteMetadata()
let title
let description
let image
let postURL
if (postSEO) {
const postMeta = post.frontmatter
title = `${postMeta.title} ¦ ${siteTitle}`
description = postMeta.description ? postMeta.description : post.excerpt
image = postMeta.image
? postMeta.image.childImageSharp.fluid.src
: `/${logo}`
postURL = `${siteUrl}${slug}`
} else {
title = `${siteTitle} ¦ ${siteDescription}`
description = siteDescription
image = `/${logo}`
}
image = `${siteUrl}${image}`
const blogURL = siteUrl
const url = postSEO ? postURL : blogURL
// const schema = createSchemaOrg(
// blogURL,
// title,
// postSEO,
// postURL,
// image,
// description,
// author
// )
return (
<MetaTags
description={description}
image={image}
url={url}
// schema={(schema as unknown) as string}
postSEO={postSEO}
title={title}
/>
)
}

View File

@ -0,0 +1,75 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import { useSiteMetadata } from '../../../hooks/use-site-metadata'
import schemaOrg from './schemaOrg'
function feedLinks(siteUrl: string) {
return (
<link
rel="alternate"
title="JSON Feed"
type="application/json"
href={`${siteUrl}/feed.json`}
/>
)
}
export default function MetaTags({
description,
image,
url,
postSEO,
title,
datePublished,
dateModified
}: {
description: string
image: string
url: string
postSEO: boolean
title: string
datePublished: string
dateModified: string
}) {
const { siteTitle, siteDescription, siteUrl, author } = useSiteMetadata()
return (
<Helmet
defaultTitle={`${siteTitle} ¦ ${siteDescription}`}
titleTemplate={`%s ¦ ${siteTitle}`}
>
<html lang="en" />
<meta name="description" content={description} />
<meta name="image" content={image} />
<link rel="canonical" href={url} />
{schemaOrg(
siteUrl,
title,
postSEO,
url,
image,
description,
author.name,
datePublished,
dateModified
)}
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<meta property="og:url" content={url} />
<meta property="og:site_name" content={siteTitle}></meta>
{postSEO && <meta property="og:type" content="article" />}
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:creator"
content={author.twitter ? author.twitter : ''}
/>
{feedLinks(siteUrl)}
</Helmet>
)
}

View File

@ -0,0 +1,67 @@
import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import { useSiteMetadata } from '../../../hooks/use-site-metadata'
import { Post } from '../../../@types/Post'
import MetaTags from './MetaTags'
const query = graphql`
query {
logo: allFile(filter: { name: { eq: "apple-touch-icon" } }) {
edges {
node {
relativePath
}
}
}
}
`
export default function SEO({
post,
slug,
postSEO
}: {
post?: Post
slug?: string
postSEO?: boolean
}) {
const data = useStaticQuery(query)
const logo = data.logo.edges[0].node.relativePath
const { siteTitle, siteUrl, siteDescription } = useSiteMetadata()
let title
let description
let image
let postURL
if (postSEO) {
const postMeta = post.frontmatter
title = `${postMeta.title} ¦ ${siteTitle}`
description = postMeta.description ? postMeta.description : post.excerpt
image = postMeta.image
? postMeta.image.childImageSharp.fluid.src
: `/${logo}`
postURL = `${siteUrl}${slug}`
} else {
title = `${siteTitle} ¦ ${siteDescription}`
description = siteDescription
image = `/${logo}`
}
image = `${siteUrl}${image}`
const blogURL = siteUrl
const url = postSEO ? postURL : blogURL
return (
<MetaTags
description={description}
image={image}
url={url}
postSEO={postSEO}
title={title}
datePublished={post && post.fields && post.fields.date}
dateModified={post && post.frontmatter.updated}
/>
)
}

View File

@ -0,0 +1,57 @@
import React from 'react'
export default function schemaOrg(
blogURL: string,
title: string,
postSEO: boolean,
postURL: string,
image: string,
description: string,
author: string,
datePublished: string,
dateModified: string
) {
const schemaOrgJSONLD: any = [
{
'@context': 'http://schema.org',
'@type': 'Blog',
url: blogURL,
name: title
}
]
if (postSEO) {
schemaOrgJSONLD.push({
'@context': 'http://schema.org',
'@type': 'BlogPosting',
author: {
'@type': 'Person',
name: author
},
publisher: {
'@type': 'Organization',
name: author
},
url: postURL,
name: title,
headline: title,
image: {
'@type': 'ImageObject',
url: image
},
description,
datePublished,
dateModified: dateModified || datePublished,
mainEntityOfPage: {
'@type': 'Blog',
'@id': blogURL
}
})
}
return (
<script type="application/ld+json">
{JSON.stringify(schemaOrgJSONLD)}
</script>
)
}