diff --git a/next-sitemap.js b/next-sitemap.js deleted file mode 100644 index 0f506a10..00000000 --- a/next-sitemap.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - siteUrl: process.env.SITE_URL || 'https://mikebifulco.com', - generateRobotsTxt: process.env.CONTEXT === 'production', // only generate robots.txt for prod - // ...other options -}; diff --git a/next.config.js b/next.config.js index 9c0bb7c1..9f82cde5 100644 --- a/next.config.js +++ b/next.config.js @@ -21,5 +21,15 @@ module.exports = withBundleAnalyzer( locales: ['en'], defaultLocale: 'en', }, + rewrites: async () => [ + { + source: '/rss.xml', + destination: '/api/rss.xml', + }, + { + source: '/sitemap.xml', + destination: '/api/sitemap.xml', + }, + ], }) ); diff --git a/package.json b/package.json index a2f87a61..337d4db5 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,7 @@ "license": "MIT", "scripts": { "analyze": "ANALYZE=true next build", - "build": "next build && next-sitemap", - "postbuild": "next-sitemap", + "build": "next build", "dev": "NODE_OPTIONS='--inspect' next dev", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", "start": "next start", @@ -53,7 +52,6 @@ "husky": ">=7.0.4", "lint-staged": "^12.1.2", "netlify-plugin-cache-nextjs": "^1.6.1", - "next-sitemap": "^1.6.203", "prettier": "^2.5.0" }, "repository": { diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 00000000..c59e0001 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,9 @@ +# * +User-agent: * +Allow: / + +# Host +Host: https://mikebifulco.com + +# Sitemaps +Sitemap: https://mikebifulco.com/sitemap.xml \ No newline at end of file diff --git a/src/components/RelatedContent/RelatedContentLinksByTag.js b/src/components/RelatedContent/RelatedContentLinksByTag.js index 90285032..615cc909 100644 --- a/src/components/RelatedContent/RelatedContentLinksByTag.js +++ b/src/components/RelatedContent/RelatedContentLinksByTag.js @@ -1,5 +1,5 @@ import { Box, Link, SimpleGrid, Text, useTheme } from '@chakra-ui/react'; -import { NextLink } from 'next/link'; +import NextLink from 'next/link'; import TagDictionary, { getTagInformation } from '../../data/ConvertKitTags'; @@ -36,7 +36,7 @@ const RelatedContentLinksByTag = ({ tags = DEFAULT_TAGS_TO_DISPLAY }) => { href={`/tags/${tag}`} key={`related-content-${tag}`} > - Articles {tagInformation.label} + {`Articles ${tagInformation.label}`} ); })} diff --git a/src/components/seo.js b/src/components/seo.js index ff8954ce..b50e04f3 100644 --- a/src/components/seo.js +++ b/src/components/seo.js @@ -88,8 +88,9 @@ const SEO = ({ content={image ? `summary_large_image` : `summary`} /> - + + { + const staticPagesDirectory = join(process.cwd(), 'src', 'pages'); + const staticPages = fs + .readdirSync(staticPagesDirectory) + .filter((staticPage) => { + return ![ + '_app.js', + '_document.js', + '[slug].js', + 'index.js', + '_error.js', + ].includes(staticPage); + }) + .map((staticPagePath) => { + return `${siteUrl}/${staticPagePath.replace('.js', '')}`; + }); + + return staticPages; +}; diff --git a/src/pages/api/rss.xml.js b/src/pages/api/rss.xml.js new file mode 100644 index 00000000..88a9a27e --- /dev/null +++ b/src/pages/api/rss.xml.js @@ -0,0 +1,9 @@ +import { getAllPosts } from '../../lib/blog'; +import { generateRSSFeed } from '../../utils/rss'; + +export default async function handler(req, res) { + const posts = await getAllPosts(); + const feed = generateRSSFeed(posts); + + res.setHeader('Content-Type', 'text/xml').status(200).send(feed); +} diff --git a/src/pages/api/sitemap.xml.js b/src/pages/api/sitemap.xml.js new file mode 100644 index 00000000..ae776345 --- /dev/null +++ b/src/pages/api/sitemap.xml.js @@ -0,0 +1,43 @@ +import { getStaticPageUrls } from '../../lib/staticPagesLoader'; +import { getAllPosts } from '../../lib/blog'; +import { getAllTags } from '../../lib/tags'; +import config from '../../config'; + +const { siteUrl } = config; + +const urlEntryForPage = (url, frequency = 'daily', priority = 1.0) => ` + + ${url} + ${new Date().toISOString()} + ${frequency} + ${priority} + +`; + +export default async function handler(req, res) { + const staticPageUrls = getStaticPageUrls(); + + const allPostUrls = (await getAllPosts()).map( + (post) => `${siteUrl}/posts/${post.frontmatter.path}` + ); + + const allTagUrls = Array.from((await getAllTags()).allTags).map( + (tag) => `${siteUrl}/tags/${tag}` + ); + + const rssURl = `${siteUrl}/rss.xml`; + const allUrls = [ + siteUrl, + rssURl, + ...staticPageUrls, + ...allPostUrls, + ...allTagUrls, + ]; + + const sitemap = ` + + ${allUrls.map((page) => urlEntryForPage(page)).join('')} + + `; + res.setHeader('Content-Type', 'text/xml').status(200).send(sitemap); +} diff --git a/src/pages/index.js b/src/pages/index.js index 2e125887..cf102d54 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -7,13 +7,10 @@ import { DefaultLayout } from '../components/Layouts'; import { Image, PostFeed, SEO } from '../components'; import { getAllPosts } from '../lib/blog'; -import { generateRSSFeed } from '../utils/rss'; export async function getStaticProps() { const posts = await getAllPosts(); - generateRSSFeed(posts); - return { props: { posts, diff --git a/src/pages/shop.js b/src/pages/shop/index.js similarity index 73% rename from src/pages/shop.js rename to src/pages/shop/index.js index d8a64c9e..3763f290 100644 --- a/src/pages/shop.js +++ b/src/pages/shop/index.js @@ -1,10 +1,10 @@ import React from 'react'; -import { Image, SEO } from '../components'; -import { DefaultLayout as Layout } from '../components/Layouts'; +import { Image, SEO } from '../../components'; +import { DefaultLayout as Layout } from '../../components/Layouts'; -import * as classes from '../styles/shop.module.scss'; -import SoldOut from '../components/soldOut'; +import * as classes from '../../styles/shop.module.scss'; +import SoldOut from '../../components/soldOut'; const Shop = () => ( diff --git a/src/pages/tags.js b/src/pages/tags/index.js similarity index 71% rename from src/pages/tags.js rename to src/pages/tags/index.js index 4f003652..17747ff3 100644 --- a/src/pages/tags.js +++ b/src/pages/tags/index.js @@ -5,12 +5,10 @@ import PropTypes from 'prop-types'; import Link from 'next/link'; import { Heading, SimpleGrid, Text, useTheme } from '@chakra-ui/react'; -import { getAllTags } from '../lib/tags'; +import { getAllTags } from '../../lib/tags'; -import { Tag, NewsletterSignup } from '../components'; -import { DefaultLayout as Layout } from '../components/Layouts'; - -import { SEO } from '../components'; +import { Tag, NewsletterSignup, SEO } from '../../components'; +import { DefaultLayout as Layout } from '../../components/Layouts'; export const getStaticProps = async () => { const tags = await getAllTags(); @@ -36,12 +34,9 @@ const TagsPage = ({ tags }) => { {tags?.map((tag) => ( - - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - {tag} - - + + {tag.name || tag} + ))} diff --git a/src/pages/work.js b/src/pages/work/index.js similarity index 89% rename from src/pages/work.js rename to src/pages/work/index.js index 0d7c8c7b..09e5ea80 100644 --- a/src/pages/work.js +++ b/src/pages/work/index.js @@ -3,10 +3,10 @@ import PropTypes from 'prop-types'; import { Box, Heading, Stack, Text, useTheme } from '@chakra-ui/react'; -import { DefaultLayout } from '../components/Layouts'; -import { ExternalWorkItem, SEO } from '../components'; +import { DefaultLayout } from '../../components/Layouts'; +import { ExternalWorkItem, SEO } from '../../components'; -import { getAllExternalReferences } from '../lib/external-references'; +import { getAllExternalReferences } from '../../lib/external-references'; export async function getStaticProps() { const articles = await getAllExternalReferences(); diff --git a/src/utils/rss.js b/src/utils/rss.js index 2ac5a34c..a571a4e6 100644 --- a/src/utils/rss.js +++ b/src/utils/rss.js @@ -1,14 +1,8 @@ import { rules } from 'eslint-config-prettier'; import { Feed } from 'feed'; -import fs from 'fs'; - import config from '../config'; export const generateRSSFeed = (posts) => { - if (process.env.NODE_ENV === 'development') { - return; - } - const { author, description, siteUrl, title } = config; const feed = new Feed({ @@ -39,8 +33,7 @@ export const generateRSSFeed = (posts) => { author: [author], date: new Date(date), }); - - // this will be mikebifulco.com/rss.xml - fs.writeFileSync('public/rss.xml', feed.rss2()); }); + + return feed.rss2(); }; diff --git a/yarn.lock b/yarn.lock index 9bf25f73..6dce1e6a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -838,11 +838,6 @@ resolved "https://registry.yarnpkg.com/@cloudinary/url-gen/-/url-gen-1.2.0.tgz#f1ce33d2b48a007685ca050d22fe32592481ded7" integrity sha512-Nd42dVANphz4o3dGc3qnZSSEvpKWFFRqKsBkUuH/5UZOQrBEyN0/cKVLoM1v8YaAm2Th2gx3yVIbwzMV1bWlCg== -"@corex/deepmerge@^2.6.34": - version "2.6.34" - resolved "https://registry.yarnpkg.com/@corex/deepmerge/-/deepmerge-2.6.34.tgz#8dd084f2bcc9cf54f6b1210a1aebd25206de2a84" - integrity sha512-5l3bQRGOoCJ1nYTxEaOW/MRuwNDq32KYatWO5rwOlOzxY4beVCrxDBaDBX5wpDn0PYm0QAul/vAC9GDHShEbTw== - "@ctrl/tinycolor@^3.4.0": version "3.4.0" resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz#c3c5ae543c897caa9c2a68630bed355be5f9990f" @@ -4907,13 +4902,6 @@ markdown-escapes@^1.0.0: resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== -matcher@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-4.0.0.tgz#a42a05a09aaed92e2d241eb91fddac689461ea51" - integrity sha512-S6x5wmcDmsDRRU/c2dkccDwQPXoFczc5+HpQ2lON8pnvHlnvHAHj5WlLVvw6n6vNyHuVugYrFohYxbS+pvFpKQ== - dependencies: - escape-string-regexp "^4.0.0" - md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -5411,15 +5399,6 @@ next-mdx-remote@^3.0.8: esbuild "^0.12.9" pkg-dir "^5.0.0" -next-sitemap@^1.6.203: - version "1.6.203" - resolved "https://registry.yarnpkg.com/next-sitemap/-/next-sitemap-1.6.203.tgz#bfa2e67fea2bab1efed60cda743e7f98dc00bb46" - integrity sha512-WigcoqIUNbXQa2GnwOiCOydGx/XHCS4kRtIPNEsc8DGX2XvJtbAJKRxcidZZ2KihTAtwwCu1XQ4Hbof4mJbvLg== - dependencies: - "@corex/deepmerge" "^2.6.34" - matcher "^4.0.0" - minimist "^1.2.5" - next@^12.0.4: version "12.0.4" resolved "https://registry.yarnpkg.com/next/-/next-12.0.4.tgz#096578b320f0faf0bd51798decb39aaf00052efe"