mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 09:13:35 +01:00
SEO componennt reorg
This commit is contained in:
parent
5f49e5e083
commit
36f18bd562
@ -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">{JSON.stringify(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, author } = 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.name
|
||||
)
|
||||
|
||||
return (
|
||||
<MetaTags
|
||||
description={description}
|
||||
image={image}
|
||||
url={url}
|
||||
schema={(schema as unknown) as string}
|
||||
postSEO={postSEO}
|
||||
title={title}
|
||||
/>
|
||||
)
|
||||
}
|
61
src/components/atoms/SEO/MetaTags.tsx
Normal file
61
src/components/atoms/SEO/MetaTags.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
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
|
||||
}: {
|
||||
description: string
|
||||
image: string
|
||||
url: string
|
||||
postSEO: boolean
|
||||
title: 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)}
|
||||
|
||||
<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>
|
||||
)
|
||||
}
|
65
src/components/atoms/SEO/index.tsx
Normal file
65
src/components/atoms/SEO/index.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
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}
|
||||
/>
|
||||
)
|
||||
}
|
43
src/components/atoms/SEO/schemaOrg.tsx
Normal file
43
src/components/atoms/SEO/schemaOrg.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function schemaOrg(
|
||||
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 (
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify(schemaOrgJSONLD)}
|
||||
</script>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user