parent
220efadfaa
commit
fb8f14a0db
5 changed files with 144 additions and 53 deletions
@ -1,73 +1,163 @@ |
|||||||
import NextHead from 'next/head'; |
import NextHead from 'next/head'; |
||||||
import siteConfig from '../content/site.json'; |
import siteConfig from '../content/site.json'; |
||||||
|
import { RoadmapType } from '../lib/roadmap'; |
||||||
|
import { roadmapTheme } from '../styles/theme'; |
||||||
|
|
||||||
type HelmetProps = { |
type HelmetProps = { |
||||||
title?: string; |
title?: string; |
||||||
keywords?: string[]; |
keywords?: string[]; |
||||||
canonical?: string; |
canonical?: string; |
||||||
description?: string; |
description?: string; |
||||||
|
roadmap?: RoadmapType; |
||||||
}; |
}; |
||||||
|
|
||||||
const Helmet = (props: HelmetProps) => ( |
function getRichSnippetJson(roadmap: RoadmapType) { |
||||||
<NextHead> |
return { |
||||||
<meta charSet='UTF-8' /> |
'@context': 'https://schema.org', |
||||||
|
'@type': 'Article', |
||||||
|
mainEntityOfPage: { |
||||||
|
'@type': 'WebPage', |
||||||
|
'@id': `https://roadmap.sh/${roadmap.id}`, |
||||||
|
}, |
||||||
|
headline: roadmap.seo.title, |
||||||
|
description: roadmap.seo.description, |
||||||
|
image: roadmap.jsonUrl |
||||||
|
? `https://roadmap.sh/roadmaps/${roadmap.id}.png` |
||||||
|
: undefined, |
||||||
|
author: { |
||||||
|
'@type': 'Person', |
||||||
|
name: 'Kamran Ahmed', |
||||||
|
url: 'https://twitter.com/kamranahmedse', |
||||||
|
}, |
||||||
|
publisher: { |
||||||
|
'@type': 'Organization', |
||||||
|
name: 'roadmap.sh', |
||||||
|
logo: { |
||||||
|
'@type': 'ImageObject', |
||||||
|
url: 'https://roadmap.sh/brand-square.png', |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
<title>{props.title || siteConfig.title}</title> |
const Helmet = (props: HelmetProps) => { |
||||||
<meta name='description' content={props.description || siteConfig.description} /> |
const { roadmap, title, canonical, description, keywords } = props; |
||||||
|
|
||||||
<meta name='author' content={siteConfig.author} /> |
return ( |
||||||
<meta name='keywords' content={props.keywords ? props.keywords.join(',') : siteConfig.keywords.join(',')} /> |
<NextHead> |
||||||
|
<meta charSet="UTF-8" /> |
||||||
|
|
||||||
<meta name='viewport' |
<title>{title || siteConfig.title}</title> |
||||||
content='width=device-width, user-scalable=yes, initial-scale=1.0, maximum-scale=3.0, minimum-scale=1.0' /> |
<meta |
||||||
{props.canonical && <link rel='canonical' href={props.canonical} />} |
name="description" |
||||||
<meta httpEquiv='Content-Language' content='en' /> |
content={description || siteConfig.description} |
||||||
|
/> |
||||||
|
|
||||||
<meta property='og:title' content={props.title || siteConfig.title} /> |
<meta name="author" content={siteConfig.author} /> |
||||||
<meta property='og:description' content={props.description || siteConfig.description} /> |
<meta |
||||||
<meta property='og:image' content={`${siteConfig.url.web}${siteConfig.logoSquare}`} /> |
name="keywords" |
||||||
<meta property='og:url' content={siteConfig.url.web} /> |
content={keywords ? keywords.join(',') : siteConfig.keywords.join(',')} |
||||||
<meta property='og:type' content='website' /> |
/> |
||||||
<meta property='article:publisher' content={`https://facebook.com/${siteConfig.facebook}`} /> |
|
||||||
<meta property='og:site_name' content={siteConfig.name} /> |
|
||||||
<meta property='article:author' content={siteConfig.author} /> |
|
||||||
|
|
||||||
<meta name='twitter:card' content='summary' /> |
<meta |
||||||
<meta name='twitter:site' content={`@${siteConfig.twitter}`} /> |
name="viewport" |
||||||
<meta name='twitter:title' content={props.title || siteConfig.title} /> |
content="width=device-width, user-scalable=yes, initial-scale=1.0, maximum-scale=3.0, minimum-scale=1.0" |
||||||
<meta name='twitter:description' content={props.description || siteConfig.description} /> |
/> |
||||||
<meta name='twitter:image' content={`${siteConfig.url.web}${siteConfig.logoSquare}`} /> |
{canonical && <link rel="canonical" href={canonical} />} |
||||||
<meta name='twitter:image:alt' content='roadmap.sh' /> |
<meta httpEquiv="Content-Language" content="en" /> |
||||||
|
|
||||||
<meta name='mobile-web-app-capable' content='yes' /> |
<meta property="og:title" content={title || siteConfig.title} /> |
||||||
<meta name='apple-mobile-web-app-capable' content='yes' /> |
<meta |
||||||
<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' /> |
property="og:description" |
||||||
<link rel='apple-touch-icon' sizes='180x180' href='/manifest/apple-touch-icon.png' /> |
content={description || siteConfig.description} |
||||||
<meta name='msapplication-TileColor' content='#101010' /> |
/> |
||||||
<meta name='theme-color' content='#848a9a' /> |
<meta |
||||||
|
property="og:image" |
||||||
|
content={`${siteConfig.url.web}${siteConfig.logoSquare}`} |
||||||
|
/> |
||||||
|
<meta property="og:url" content={siteConfig.url.web} /> |
||||||
|
<meta property="og:type" content="website" /> |
||||||
|
<meta |
||||||
|
property="article:publisher" |
||||||
|
content={`https://facebook.com/${siteConfig.facebook}`} |
||||||
|
/> |
||||||
|
<meta property="og:site_name" content={siteConfig.name} /> |
||||||
|
<meta property="article:author" content={siteConfig.author} /> |
||||||
|
|
||||||
<link rel='manifest' href='/manifest/manifest.json' /> |
<meta name="twitter:card" content="summary" /> |
||||||
<link rel='icon' type='image/png' sizes='32x32' href='/manifest/icon32.png' /> |
<meta name="twitter:site" content={`@${siteConfig.twitter}`} /> |
||||||
<link rel='icon' type='image/png' sizes='16x16' href='/manifest/icon16.png' /> |
<meta name="twitter:title" content={title || siteConfig.title} /> |
||||||
<link rel='shortcut icon' href='/manifest/favicon.ico' type='image/x-icon' /> |
<meta |
||||||
<link rel='icon' href='/manifest/favicon.ico' type='image/x-icon' /> |
name="twitter:description" |
||||||
|
content={description || siteConfig.description} |
||||||
|
/> |
||||||
|
<meta |
||||||
|
name="twitter:image" |
||||||
|
content={`${siteConfig.url.web}${siteConfig.logoSquare}`} |
||||||
|
/> |
||||||
|
<meta name="twitter:image:alt" content="roadmap.sh" /> |
||||||
|
|
||||||
{ /* Global Site Tag (gtag.js) - Google Analytics */} |
<meta name="mobile-web-app-capable" content="yes" /> |
||||||
{process.env.GA_SECRET && ( |
<meta name="apple-mobile-web-app-capable" content="yes" /> |
||||||
<> |
<meta |
||||||
<script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GA_SECRET}`} /> |
name="apple-mobile-web-app-status-bar-style" |
||||||
<script dangerouslySetInnerHTML={{ |
content="black-translucent" |
||||||
__html: ` |
/> |
||||||
|
<link |
||||||
|
rel="apple-touch-icon" |
||||||
|
sizes="180x180" |
||||||
|
href="/manifest/apple-touch-icon.png" |
||||||
|
/> |
||||||
|
<meta name="msapplication-TileColor" content="#101010" /> |
||||||
|
<meta name="theme-color" content="#848a9a" /> |
||||||
|
|
||||||
|
<link rel="manifest" href="/manifest/manifest.json" /> |
||||||
|
<link |
||||||
|
rel="icon" |
||||||
|
type="image/png" |
||||||
|
sizes="32x32" |
||||||
|
href="/manifest/icon32.png" |
||||||
|
/> |
||||||
|
<link |
||||||
|
rel="icon" |
||||||
|
type="image/png" |
||||||
|
sizes="16x16" |
||||||
|
href="/manifest/icon16.png" |
||||||
|
/> |
||||||
|
<link |
||||||
|
rel="shortcut icon" |
||||||
|
href="/manifest/favicon.ico" |
||||||
|
type="image/x-icon" |
||||||
|
/> |
||||||
|
<link rel="icon" href="/manifest/favicon.ico" type="image/x-icon" /> |
||||||
|
|
||||||
|
{roadmap?.id && ( |
||||||
|
<script type="application/ld+json"> |
||||||
|
{JSON.stringify(getRichSnippetJson(roadmap))} |
||||||
|
</script> |
||||||
|
)} |
||||||
|
|
||||||
|
{/* Global Site Tag (gtag.js) - Google Analytics */} |
||||||
|
{process.env.GA_SECRET && ( |
||||||
|
<> |
||||||
|
<script |
||||||
|
async |
||||||
|
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GA_SECRET}`} |
||||||
|
/> |
||||||
|
<script |
||||||
|
dangerouslySetInnerHTML={{ |
||||||
|
__html: ` |
||||||
window.dataLayer = window.dataLayer || []; |
window.dataLayer = window.dataLayer || []; |
||||||
function gtag(){dataLayer.push(arguments);} |
function gtag(){dataLayer.push(arguments);} |
||||||
gtag('js', new Date()); |
gtag('js', new Date()); |
||||||
gtag('config', '${process.env.GA_SECRET}'); |
gtag('config', '${process.env.GA_SECRET}'); |
||||||
` |
`,
|
||||||
}} /> |
}} |
||||||
</> |
/> |
||||||
)} |
</> |
||||||
|
)} |
||||||
</NextHead> |
</NextHead> |
||||||
); |
); |
||||||
|
}; |
||||||
|
|
||||||
export default Helmet; |
export default Helmet; |
||||||
|
After Width: | Height: | Size: 93 KiB |
Loading…
Reference in new issue