upstream #1
@ -2,57 +2,72 @@ import Head from 'next/head'
|
|||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
|
|
||||||
export const PageSeo = ({ title, description }) => {
|
const CommonSEO = ({ title, description, ogType, ogImage, twImage }) => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<title>{`${title}`}</title>
|
<title>{title}</title>
|
||||||
<meta name="robots" content="follow, index" />
|
<meta name="robots" content="follow, index" />
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
<meta property="og:url" content={`${siteMetadata.siteUrl}${router.asPath}`} />
|
<meta property="og:url" content={`${siteMetadata.siteUrl}${router.asPath}`} />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content={ogType} />
|
||||||
<meta property="og:site_name" content={siteMetadata.title} />
|
<meta property="og:site_name" content={siteMetadata.title} />
|
||||||
<meta property="og:description" content={description} />
|
<meta property="og:description" content={description} />
|
||||||
<meta property="og:title" content={title} />
|
<meta property="og:title" content={title} />
|
||||||
<meta property="og:image" content={`${siteMetadata.siteUrl}${siteMetadata.socialBanner}`} />
|
{ogImage.constructor.name === 'Array' ? (
|
||||||
|
ogImage.map(({ url }) => <meta property="og:image" content={url} key={url} />)
|
||||||
|
) : (
|
||||||
|
<meta property="og:image" content={ogImage} key={ogImage} />
|
||||||
|
)}
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:site" content={siteMetadata.twitter} />
|
<meta name="twitter:site" content={siteMetadata.twitter} />
|
||||||
<meta name="twitter:title" content={title} />
|
<meta name="twitter:title" content={title} />
|
||||||
<meta name="twitter:description" content={description} />
|
<meta name="twitter:description" content={description} />
|
||||||
<meta name="twitter:image" content={`${siteMetadata.siteUrl}${siteMetadata.socialBanner}`} />
|
<meta name="twitter:image" content={twImage} />
|
||||||
</Head>
|
</Head>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TagSeo = ({ title, description }) => {
|
export const PageSEO = ({ title, description }) => {
|
||||||
|
const ogImageUrl = siteMetadata.siteUrl + siteMetadata.socialBanner
|
||||||
|
const twImageUrl = siteMetadata.siteUrl + siteMetadata.socialBanner
|
||||||
|
return (
|
||||||
|
<CommonSEO
|
||||||
|
title={title}
|
||||||
|
description={description}
|
||||||
|
ogType="website"
|
||||||
|
ogImage={ogImageUrl}
|
||||||
|
twImage={twImageUrl}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TagSEO = ({ title, description }) => {
|
||||||
|
const ogImageUrl = siteMetadata.siteUrl + siteMetadata.socialBanner
|
||||||
|
const twImageUrl = siteMetadata.siteUrl + siteMetadata.socialBanner
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
return (
|
return (
|
||||||
<Head>
|
<>
|
||||||
<title>{`${title}`}</title>
|
<CommonSEO
|
||||||
<meta name="robots" content="follow, index" />
|
title={title}
|
||||||
<meta name="description" content={description} />
|
description={description}
|
||||||
<meta property="og:url" content={`${siteMetadata.siteUrl}${router.asPath}`} />
|
ogType="website"
|
||||||
<meta property="og:type" content="website" />
|
ogImage={ogImageUrl}
|
||||||
<meta property="og:site_name" content={siteMetadata.title} />
|
twImage={twImageUrl}
|
||||||
<meta property="og:description" content={description} />
|
|
||||||
<meta property="og:title" content={title} />
|
|
||||||
<meta property="og:image" content={`${siteMetadata.siteUrl}${siteMetadata.socialBanner}`} />
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta name="twitter:site" content={siteMetadata.twitter} />
|
|
||||||
<meta name="twitter:title" content={title} />
|
|
||||||
<meta name="twitter:description" content={description} />
|
|
||||||
<meta name="twitter:image" content={`${siteMetadata.siteUrl}${siteMetadata.socialBanner}`} />
|
|
||||||
<link
|
|
||||||
rel="alternate"
|
|
||||||
type="application/rss+xml"
|
|
||||||
title={`${description} - RSS feed`}
|
|
||||||
href={`${siteMetadata.siteUrl}${router.asPath}/feed.xml`}
|
|
||||||
/>
|
/>
|
||||||
</Head>
|
<Head>
|
||||||
|
<link
|
||||||
|
rel="alternate"
|
||||||
|
type="application/rss+xml"
|
||||||
|
title={`${description} - RSS feed`}
|
||||||
|
href={`${siteMetadata.siteUrl}${router.asPath}/feed.xml`}
|
||||||
|
/>
|
||||||
|
</Head>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BlogSeo = ({ authorDetails, title, summary, date, lastmod, url, images = [] }) => {
|
export const BlogSEO = ({ authorDetails, title, summary, date, lastmod, url, images = [] }) => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const publishedAt = new Date(date).toISOString()
|
const publishedAt = new Date(date).toISOString()
|
||||||
const modifiedAt = new Date(lastmod || date).toISOString()
|
const modifiedAt = new Date(lastmod || date).toISOString()
|
||||||
@ -108,31 +123,26 @@ export const BlogSeo = ({ authorDetails, title, summary, date, lastmod, url, ima
|
|||||||
description: summary,
|
description: summary,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const twImageUrl = featuredImages[0].url
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<CommonSEO
|
||||||
|
title={title}
|
||||||
|
description={summary}
|
||||||
|
ogType="article"
|
||||||
|
ogImage={featuredImages}
|
||||||
|
twImage={twImageUrl}
|
||||||
|
/>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{`${title}`}</title>
|
|
||||||
<meta name="robots" content="follow, index" />
|
|
||||||
<meta name="description" content={summary} />
|
|
||||||
<meta property="og:url" content={`${siteMetadata.siteUrl}${router.asPath}`} />
|
|
||||||
<meta property="og:type" content="article" />
|
|
||||||
<meta property="og:site_name" content={siteMetadata.title} />
|
|
||||||
<meta property="og:description" content={summary} />
|
|
||||||
<meta property="og:title" content={title} />
|
|
||||||
{featuredImages.map((img) => (
|
|
||||||
<meta property="og:image" content={img.url} key={img.url} />
|
|
||||||
))}
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta name="twitter:site" content={siteMetadata.twitter} />
|
|
||||||
<meta name="twitter:title" content={title} />
|
|
||||||
<meta name="twitter:description" content={summary} />
|
|
||||||
<meta name="twitter:image" content={featuredImages[0].url} />
|
|
||||||
{date && <meta property="article:published_time" content={publishedAt} />}
|
{date && <meta property="article:published_time" content={publishedAt} />}
|
||||||
{lastmod && <meta property="article:modified_time" content={modifiedAt} />}
|
{lastmod && <meta property="article:modified_time" content={modifiedAt} />}
|
||||||
<link rel="canonical" href={`${siteMetadata.siteUrl}${router.asPath}`} />
|
<link rel="canonical" href={`${siteMetadata.siteUrl}${router.asPath}`} />
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData, null, 2) }}
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: JSON.stringify(structuredData, null, 2),
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
</>
|
</>
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import SocialIcon from '@/components/social-icons'
|
import SocialIcon from '@/components/social-icons'
|
||||||
import Image from '@/components/Image'
|
import Image from '@/components/Image'
|
||||||
import { PageSeo } from '@/components/SEO'
|
import { PageSEO } from '@/components/SEO'
|
||||||
|
|
||||||
export default function AuthorLayout({ children, frontMatter }) {
|
export default function AuthorLayout({ children, frontMatter }) {
|
||||||
const { name, avatar, occupation, company, email, twitter, linkedin, github } = frontMatter
|
const { name, avatar, occupation, company, email, twitter, linkedin, github } = frontMatter
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSeo title={`About - ${name}`} description={`About me - ${name}`} />
|
<PageSEO title={`About - ${name}`} description={`About me - ${name}`} />
|
||||||
<div className="divide-y">
|
<div className="divide-y">
|
||||||
<div className="pt-6 pb-8 space-y-2 md:space-y-5">
|
<div className="pt-6 pb-8 space-y-2 md:space-y-5">
|
||||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Link from '@/components/Link'
|
import Link from '@/components/Link'
|
||||||
import PageTitle from '@/components/PageTitle'
|
import PageTitle from '@/components/PageTitle'
|
||||||
import SectionContainer from '@/components/SectionContainer'
|
import SectionContainer from '@/components/SectionContainer'
|
||||||
import { BlogSeo } from '@/components/SEO'
|
import { BlogSEO } from '@/components/SEO'
|
||||||
import Image from '@/components/Image'
|
import Image from '@/components/Image'
|
||||||
import Tag from '@/components/Tag'
|
import Tag from '@/components/Tag'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
@ -20,7 +20,7 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<BlogSeo
|
<BlogSEO
|
||||||
url={`${siteMetadata.siteUrl}/blog/${slug}`}
|
url={`${siteMetadata.siteUrl}/blog/${slug}`}
|
||||||
authorDetails={authorDetails}
|
authorDetails={authorDetails}
|
||||||
{...frontMatter}
|
{...frontMatter}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Link from '@/components/Link'
|
import Link from '@/components/Link'
|
||||||
import PageTitle from '@/components/PageTitle'
|
import PageTitle from '@/components/PageTitle'
|
||||||
import SectionContainer from '@/components/SectionContainer'
|
import SectionContainer from '@/components/SectionContainer'
|
||||||
import { BlogSeo } from '@/components/SEO'
|
import { BlogSEO } from '@/components/SEO'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import formatDate from '@/lib/utils/formatDate'
|
import formatDate from '@/lib/utils/formatDate'
|
||||||
import Comments from '@/components/comments'
|
import Comments from '@/components/comments'
|
||||||
@ -11,7 +11,7 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<BlogSeo url={`${siteMetadata.siteUrl}/blog/${frontMatter.slug}`} {...frontMatter} />
|
<BlogSEO url={`${siteMetadata.siteUrl}/blog/${frontMatter.slug}`} {...frontMatter} />
|
||||||
<article>
|
<article>
|
||||||
<div>
|
<div>
|
||||||
<header>
|
<header>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import ListLayout from '@/layouts/ListLayout'
|
import ListLayout from '@/layouts/ListLayout'
|
||||||
import { PageSeo } from '@/components/SEO'
|
import { PageSEO } from '@/components/SEO'
|
||||||
|
|
||||||
export const POSTS_PER_PAGE = 5
|
export const POSTS_PER_PAGE = 5
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ export async function getStaticProps() {
|
|||||||
export default function Blog({ posts, initialDisplayPosts, pagination }) {
|
export default function Blog({ posts, initialDisplayPosts, pagination }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSeo title={`Blog - ${siteMetadata.author}`} description={siteMetadata.description} />
|
<PageSEO title={`Blog - ${siteMetadata.author}`} description={siteMetadata.description} />
|
||||||
<ListLayout
|
<ListLayout
|
||||||
posts={posts}
|
posts={posts}
|
||||||
initialDisplayPosts={initialDisplayPosts}
|
initialDisplayPosts={initialDisplayPosts}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { PageSeo } from '@/components/SEO'
|
import { PageSEO } from '@/components/SEO'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
||||||
import ListLayout from '@/layouts/ListLayout'
|
import ListLayout from '@/layouts/ListLayout'
|
||||||
@ -44,7 +44,7 @@ export async function getStaticProps(context) {
|
|||||||
export default function PostPage({ posts, initialDisplayPosts, pagination }) {
|
export default function PostPage({ posts, initialDisplayPosts, pagination }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSeo title={siteMetadata.title} description={siteMetadata.description} />
|
<PageSEO title={siteMetadata.title} description={siteMetadata.description} />
|
||||||
<ListLayout
|
<ListLayout
|
||||||
posts={posts}
|
posts={posts}
|
||||||
initialDisplayPosts={initialDisplayPosts}
|
initialDisplayPosts={initialDisplayPosts}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Link from '@/components/Link'
|
import Link from '@/components/Link'
|
||||||
import { PageSeo } from '@/components/SEO'
|
import { PageSEO } from '@/components/SEO'
|
||||||
import Tag from '@/components/Tag'
|
import Tag from '@/components/Tag'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
||||||
@ -16,7 +16,7 @@ export async function getStaticProps() {
|
|||||||
export default function Home({ posts }) {
|
export default function Home({ posts }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSeo title={siteMetadata.title} description={siteMetadata.description} />
|
<PageSEO title={siteMetadata.title} description={siteMetadata.description} />
|
||||||
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
||||||
<div className="pt-6 pb-8 space-y-2 md:space-y-5">
|
<div className="pt-6 pb-8 space-y-2 md:space-y-5">
|
||||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import projectsData from '@/data/projectsData'
|
import projectsData from '@/data/projectsData'
|
||||||
import Image from '@/components/Image'
|
|
||||||
import Link from '@/components/Link'
|
|
||||||
import Card from '@/components/Card'
|
import Card from '@/components/Card'
|
||||||
import { PageSeo } from '@/components/SEO'
|
import { PageSEO } from '@/components/SEO'
|
||||||
|
|
||||||
export default function Projects() {
|
export default function Projects() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSeo title={`Projects - ${siteMetadata.author}`} description={siteMetadata.description} />
|
<PageSEO title={`Projects - ${siteMetadata.author}`} description={siteMetadata.description} />
|
||||||
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
||||||
<div className="pt-6 pb-8 space-y-2 md:space-y-5">
|
<div className="pt-6 pb-8 space-y-2 md:space-y-5">
|
||||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Link from '@/components/Link'
|
import Link from '@/components/Link'
|
||||||
import { PageSeo } from '@/components/SEO'
|
import { PageSEO } from '@/components/SEO'
|
||||||
import Tag from '@/components/Tag'
|
import Tag from '@/components/Tag'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import { getAllTags } from '@/lib/tags'
|
import { getAllTags } from '@/lib/tags'
|
||||||
@ -15,7 +15,7 @@ export default function Tags({ tags }) {
|
|||||||
const sortedTags = Object.keys(tags).sort((a, b) => tags[b] - tags[a])
|
const sortedTags = Object.keys(tags).sort((a, b) => tags[b] - tags[a])
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSeo title={`Tags - ${siteMetadata.author}`} description="Things I blog about" />
|
<PageSEO title={`Tags - ${siteMetadata.author}`} description="Things I blog about" />
|
||||||
<div className="flex flex-col items-start justify-start divide-y divide-gray-200 dark:divide-gray-700 md:justify-center md:items-center md:divide-y-0 md:flex-row md:space-x-6 md:mt-24">
|
<div className="flex flex-col items-start justify-start divide-y divide-gray-200 dark:divide-gray-700 md:justify-center md:items-center md:divide-y-0 md:flex-row md:space-x-6 md:mt-24">
|
||||||
<div className="pt-6 pb-8 space-x-2 md:space-y-5">
|
<div className="pt-6 pb-8 space-x-2 md:space-y-5">
|
||||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14 md:border-r-2 md:px-6">
|
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14 md:border-r-2 md:px-6">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TagSeo } from '@/components/SEO'
|
import { TagSEO } from '@/components/SEO'
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import ListLayout from '@/layouts/ListLayout'
|
import ListLayout from '@/layouts/ListLayout'
|
||||||
import generateRss from '@/lib/generate-rss'
|
import generateRss from '@/lib/generate-rss'
|
||||||
@ -43,9 +43,9 @@ export default function Tag({ posts, tag }) {
|
|||||||
const title = tag[0].toUpperCase() + tag.split(' ').join('-').slice(1)
|
const title = tag[0].toUpperCase() + tag.split(' ').join('-').slice(1)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TagSeo
|
<TagSEO
|
||||||
title={`${tag} - ${siteMetadata.title}`}
|
title={`${tag} - ${siteMetadata.author}`}
|
||||||
description={`${tag} tags - ${siteMetadata.title}`}
|
description={`${tag} tags - ${siteMetadata.author}`}
|
||||||
/>
|
/>
|
||||||
<ListLayout posts={posts} title={title} />
|
<ListLayout posts={posts} title={title} />
|
||||||
</>
|
</>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user