Add support for rich snippets

pull/954/head
Kamran Ahmed 3 years ago
parent 220efadfaa
commit fb8f14a0db
  1. 188
      components/helmet.tsx
  2. 4
      content/roadmaps/100-frontend/meta.json
  3. 4
      content/roadmaps/101-backend/meta.json
  4. 1
      pages/[roadmap]/index.tsx
  5. BIN
      public/roadmaps/android.png

@ -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;

@ -1,7 +1,7 @@
{ {
"seo": { "seo": {
"title": "Learn to become a modern frontend developer", "title": "Frontend Developer Roadmap: Learn to become a modern frontend developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for modern frontend development. Learn to become a modern frontend developer by following the steps, skills, resources and guides listed in this roadmap.", "description": "Learn to become a modern frontend developer using this roadmap. Community driven, articles, resources, guides, interview questions, quizzes for modern frontend development.",
"keywords": [ "keywords": [
"guide to becoming a developer", "guide to becoming a developer",
"guide to becoming a frontend developer", "guide to becoming a frontend developer",

@ -1,7 +1,7 @@
{ {
"seo": { "seo": {
"title": "Learn to become a modern backend developer", "title": "Backend Developer Roadmap: Learn to become a modern backend developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for modern backend development. Learn to become a modern backend developer by following the steps, skills, resources and guides listed in this roadmap.", "description": "Learn to become a modern backend developer using this roadmap. Community driven, articles, resources, guides, interview questions, quizzes for modern backend development.",
"keywords": [ "keywords": [
"guide to becoming a developer", "guide to becoming a developer",
"guide to becoming a backend developer", "guide to becoming a backend developer",

@ -63,6 +63,7 @@ export default function Roadmap(props: RoadmapProps) {
title={roadmap?.seo?.title || roadmap.title} title={roadmap?.seo?.title || roadmap.title}
description={roadmap?.seo?.description || roadmap.description} description={roadmap?.seo?.description || roadmap.description}
keywords={roadmap?.seo.keywords || []} keywords={roadmap?.seo.keywords || []}
roadmap={roadmap}
/> />
<Box mb="60px"> <Box mb="60px">
<RoadmapPageHeader roadmap={roadmap} /> <RoadmapPageHeader roadmap={roadmap} />

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Loading…
Cancel
Save