1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-04-26 20:08:29 -04:00
jarv.is/pages/notes/[slug].tsx

96 lines
2.9 KiB
TypeScript

import { InView } from "react-intersection-observer";
import { NextSeo, ArticleJsonLd } from "next-seo";
import { MDXRemote } from "next-mdx-remote";
import { htmlEscape } from "escape-goat";
import Content from "../../components/Content/Content";
import NoteMeta from "../../components/NoteMeta/NoteMeta";
import NoteTitle from "../../components/NoteTitle/NoteTitle";
import Comments from "../../components/Comments/Comments";
import * as mdxComponents from "../../lib/mdx-components";
import { getNote, getNoteSlugs } from "../../lib/parse-notes";
import * as config from "../../lib/config";
import { articleJsonLd } from "../../lib/seo";
import type { GetStaticProps, GetStaticPaths } from "next";
import type { NoteType } from "../../types";
const Note = ({ frontMatter, source }: NoteType) => {
return (
<>
<NextSeo
title={frontMatter.title}
description={frontMatter.description}
canonical={frontMatter.permalink}
openGraph={{
title: frontMatter.title,
url: frontMatter.permalink,
type: "article",
article: {
authors: [config.authorName],
tags: frontMatter.tags,
publishedTime: frontMatter.date,
modifiedTime: frontMatter.date,
},
images: frontMatter.image && [
{
url: `${config.baseUrl}${frontMatter.image}`,
alt: frontMatter.title,
},
],
}}
twitter={{
cardType: "summary_large_image",
}}
/>
<ArticleJsonLd
url={frontMatter.permalink}
title={htmlEscape(frontMatter.title)}
description={htmlEscape(frontMatter.description)}
datePublished={frontMatter.date}
dateModified={frontMatter.date}
images={frontMatter.image && [`${config.baseUrl}${frontMatter.image}`]}
{...articleJsonLd}
/>
<NoteMeta slug={frontMatter.slug} date={frontMatter.date} title={frontMatter.title} tags={frontMatter.tags} />
<NoteTitle slug={frontMatter.slug} htmlTitle={frontMatter.htmlTitle} />
<Content>
{/* @ts-ignore */}
<MDXRemote {...source} components={{ ...mdxComponents }} />
</Content>
{frontMatter.noComments !== true && (
<InView rootMargin="140px" triggerOnce fallbackInView>
{({ inView, ref }) => (
<div id="comments" ref={ref}>
{inView && <Comments title={frontMatter.title} />}
</div>
)}
</InView>
)}
</>
);
};
export const getStaticProps: GetStaticProps = async ({ params }) => {
const { frontMatter, source } = await getNote(params.slug as string);
return {
props: {
frontMatter,
source,
},
};
};
export const getStaticPaths: GetStaticPaths = async () => {
const paths = getNoteSlugs().map((slug) => ({ params: { slug } }));
return {
paths,
fallback: false,
};
};
export default Note;