From d9bab3cedbb75c34599acc6f3d4892ddaf02902b Mon Sep 17 00:00:00 2001 From: Theodorus Clarence Date: Fri, 31 Dec 2021 18:27:19 +0700 Subject: [PATCH] feat: add rss --- .gitignore | 5 ++- src/components/Tooltip.tsx | 3 +- src/components/layout/Footer.tsx | 54 +++++++++++++++++++++++--------- src/lib/rss.ts | 49 +++++++++++++++++++++++++++++ src/pages/index.tsx | 3 ++ 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 src/lib/rss.ts diff --git a/.gitignore b/.gitignore index 83a48ee7..d541c36a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,7 @@ sitemap.xml # cypress cypress/videos -cypress/screenshots \ No newline at end of file +cypress/screenshots + +# rss +rss.xml \ No newline at end of file diff --git a/src/components/Tooltip.tsx b/src/components/Tooltip.tsx index 700b2f06..6caafdc9 100644 --- a/src/components/Tooltip.tsx +++ b/src/components/Tooltip.tsx @@ -8,7 +8,8 @@ type TooltipTextProps = { className?: string; spanClassName?: string; withUnderline?: boolean; -} & TooltipProps; +} & TooltipProps & + Omit, 'children' | 'className'>; export default function Tooltip({ content, diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx index 1f757ad1..e585ec87 100644 --- a/src/components/layout/Footer.tsx +++ b/src/components/layout/Footer.tsx @@ -2,13 +2,14 @@ import * as React from 'react'; import CopyToClipboard from 'react-copy-to-clipboard'; import { FiMail } from 'react-icons/fi'; import { SiGithub, SiLinkedin, SiTwitter } from 'react-icons/si'; -import { Tooltip } from 'react-tippy'; +import { Tooltip as TooltipTippy } from 'react-tippy'; import { trackEvent } from '@/lib/analytics'; import Accent from '@/components/Accent'; import Spotify from '@/components/layout/Spotify'; import UnstyledLink from '@/components/links/UnstyledLink'; +import Tooltip from '@/components/Tooltip'; import { spotifyFlag } from '@/constants/env'; @@ -60,7 +61,7 @@ function SocialLinks() { return (
- - +
{socials.map((social) => ( - { - trackEvent(`Footer Link: ${social.text}`, 'link'); - }} + - - + { + trackEvent(`Footer Link: ${social.text}`, 'link'); + }} + > + + + ))}
); @@ -134,22 +141,39 @@ const footerLinks = [ href: '/subscribe', text: 'Subscribe', }, + { + href: 'https://theodorusclarence.com/rss.xml', + text: 'RSS', + }, ]; const socials = [ { href: 'https://clarence.link/github', icon: SiGithub, - text: 'Github', + text: ( + <> + See my projects on Github + + ), }, { href: 'https://clarence.link/linkedin', icon: SiLinkedin, - text: 'Linkedin', + text: ( + <> + Find me on Linkedin + + ), }, { href: 'https://clarence.link/twt', icon: SiTwitter, - text: 'Twitter', + text: ( + <> + I post updates, tips, insight, and sometimes do some talk. Follow me on{' '} + Twitter! + + ), }, ]; diff --git a/src/lib/rss.ts b/src/lib/rss.ts new file mode 100644 index 00000000..beb03d79 --- /dev/null +++ b/src/lib/rss.ts @@ -0,0 +1,49 @@ +import format from 'date-fns/format'; +import fs from 'fs'; + +import { getAllFilesFrontmatter } from '@/lib/mdx'; + +export async function getRssXml() { + const frontmatters = await getAllFilesFrontmatter('blog'); + + const blogUrl = 'https://theodorusclarence.com/blog'; + + const itemXml = frontmatters + .filter((fm) => !fm.slug.startsWith('id-')) + .map(({ slug, title, description, publishedAt, lastUpdated }) => + ` + + ${cdata(title)} + ${cdata(description)} + ${blogUrl}/${slug} + ${blogUrl}/${slug} + ${format( + new Date(lastUpdated ?? publishedAt), + 'yyyy-MM-ii' + )} + + `.trim() + ); + + return ` + + + Theodorus Clarence Blog + ${blogUrl} + The Theodorus Clarence Blog, thoughts, mental models, and tutorials about front-end development. + en + 40 + ${itemXml.join('\n')} + + + `.trim(); +} + +function cdata(s: string) { + return ``; +} + +export async function generateRss() { + const xml = await getRssXml(); + fs.writeFileSync('public/rss.xml', xml); +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 6447b9ad..fcf53c78 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -6,6 +6,7 @@ import { InView } from 'react-intersection-observer'; import { trackEvent } from '@/lib/analytics'; import { getAllFilesFrontmatter, getFeatured } from '@/lib/mdx'; +import { generateRss } from '@/lib/rss'; import useInjectContentMeta from '@/hooks/useInjectContentMeta'; import useLoaded from '@/hooks/useLoaded'; @@ -287,6 +288,8 @@ export default function IndexPage({ } export async function getStaticProps() { + generateRss(); + const blogs = await getAllFilesFrontmatter('blog'); const projects = await getAllFilesFrontmatter('projects'); const library = await getAllFilesFrontmatter('library');