feat: better sitemap; ISR
This commit is contained in:
parent
f765c692af
commit
83c98908f5
11 changed files with 194 additions and 93 deletions
|
@ -1,13 +1,15 @@
|
|||
const fs = require("fs");
|
||||
const fm = require("front-matter");
|
||||
|
||||
const siteUrl = process.env.SITE_URL || "https://www.aaronjy.me";
|
||||
/** @type {import('next-sitemap').IConfig} */
|
||||
module.exports = {
|
||||
siteUrl: process.env.SITE_URL || "https://www.aaronjy.me",
|
||||
siteUrl,
|
||||
changefreq: "weekly",
|
||||
generateRobotsTxt: true,
|
||||
autoLastmod: false,
|
||||
generateIndexSitemap: false,
|
||||
exclude: ["/server-sitemap-index.xml"], // <= exclude here
|
||||
robotsTxtOptions: {
|
||||
policies: [
|
||||
{
|
||||
|
@ -15,30 +17,25 @@ module.exports = {
|
|||
allow: "/",
|
||||
},
|
||||
],
|
||||
additionalSitemaps: [
|
||||
`${siteUrl}/server-sitemap-index.xml`, // <==== Add here
|
||||
],
|
||||
},
|
||||
// transform: async (config, path) => {
|
||||
// const metadata = {
|
||||
// loc: path
|
||||
// }
|
||||
transform: async (config, path) => {
|
||||
const metadata = {
|
||||
loc: path,
|
||||
};
|
||||
|
||||
// if (isHomepage(path)) {
|
||||
// metadata.priority = 1
|
||||
// } else if (isBasePage(path)) {
|
||||
// metadata.priority = 0.8
|
||||
// } else {
|
||||
// if (isArticle(path)) {
|
||||
// metadata.priority = 0.6
|
||||
// const attributes = getArticleAttibutes(`content${path}.md`)
|
||||
// if (!attributes) { return null }
|
||||
if (isHomepage(path)) {
|
||||
metadata.priority = 1;
|
||||
} else if (isBasePage(path)) {
|
||||
metadata.priority = 0.8;
|
||||
} else if (isArticle(path)) {
|
||||
metadata.priority = 0.6;
|
||||
}
|
||||
|
||||
// metadata.lastmod = attributes.moddate ?? attributes.pubdate ?? null
|
||||
|
||||
// console.log('Calculated sitemap dates for article', path)
|
||||
// }
|
||||
// }
|
||||
|
||||
// return metadata
|
||||
// }
|
||||
return metadata;
|
||||
},
|
||||
};
|
||||
|
||||
function isHomepage(path) {
|
||||
|
@ -50,20 +47,5 @@ function isBasePage(path) {
|
|||
}
|
||||
|
||||
function isArticle(path) {
|
||||
return path.startsWith("/writing/");
|
||||
}
|
||||
|
||||
function getArticleAttibutes(path) {
|
||||
const fileContents = fs.readFileSync(path, {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
const { attributes } = fm(fileContents);
|
||||
|
||||
return {
|
||||
...attributes,
|
||||
pubdate: attributes.pubdate?.toUTCString() ?? null,
|
||||
moddate: attributes.moddate?.toUTCString() ?? null,
|
||||
};
|
||||
return path.startsWith("/writing/") || path.startsWith("/library/");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "www-aaronjy-me",
|
||||
"version": "2.1.2",
|
||||
"version": "2.2.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"lint-staged": {
|
||||
|
|
|
@ -7,3 +7,4 @@ Host: https://www.aaronjy.me
|
|||
|
||||
# Sitemaps
|
||||
Sitemap: https://www.aaronjy.me/sitemap.xml
|
||||
Sitemap: https://www.aaronjy.me/server-sitemap-index.xml
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
|
||||
<url><loc>https://www.aaronjy.me/</loc><priority>1</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/about/</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/cv/</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/tags/</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/attitudes-to-reading/</loc><priority>0.6</priority><pubdate>Tue, 18 Mar 2025 00:00:00 GMT</pubdate></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/moving-from-github-to-forgejo/</loc><priority>0.6</priority><pubdate>Sun, 16 Mar 2025 00:00:00 GMT</pubdate></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/performance-considerations-tcp-game-server/</loc><priority>0.6</priority><pubdate>Sun, 23 Feb 2025 21:12:37 GMT</pubdate></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/quick-reflection-katherine-may/</loc><priority>0.6</priority><pubdate>Sun, 09 Mar 2025 00:00:00 GMT</pubdate></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/static-site-on-google-cloud/</loc><priority>0.6</priority><pubdate>Wed, 01 May 2024 00:00:00 GMT</pubdate></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/support-content-filte-structure-changes-on-a-static-site/</loc><priority>0.6</priority><pubdate>Mon, 18 Mar 2024 16:47:32 GMT</pubdate></url>
|
||||
</urlset>
|
|
@ -1,7 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
|
||||
<url><loc>https://www.aaronjy.me/cv</loc><changefreq>weekly</changefreq><priority>0.7</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library</loc><changefreq>weekly</changefreq><priority>0.7</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/tags</loc><changefreq>weekly</changefreq><priority>0.7</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing</loc><changefreq>weekly</changefreq><priority>0.7</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/cv</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/tags</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-alchemist</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-invisible-man</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/wintering-the-power-of-rest-and-retreat-in-difficult-times</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-time-machine</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/when-the-moon-hits-your-eye</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-song-of-achilles</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/to-be-taught-if-fortunate</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/on-tyranny</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-dangers-of-smoking-in-bed</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-midnight-library</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/a-night-to-remember</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/sex-punishment</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/a-monster-calls</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/diary-of-an-oxygen-thief</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/1984</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/alices-adventures-in-wonderland</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-nature-of-alexander</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/test</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/eleven-kinds-of-loneliness</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/star-maker</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/stray-reflections</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/stasiland-stories-from-behind-the-berlin-wall</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/cities-that-shaped-the-ancient-world</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/animal-farm</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/a-wizard-of-earthsea</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/one-thousand-and-one-nights-a-retelling</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-tombs-of-atuan</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/childhoods-end</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/library/the-farthest-shore</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/about</loc><priority>0.8</priority></url>
|
||||
<url><loc>https://www.aaronjy.me</loc><priority>1</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/migrating-from-github-to-forgejo</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/performance-considerations-when-writing-a-tcp-game-server-in-dotnet</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/deploying-aaronjy-me-on-a-google-storage-bucket</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/supporting-content-file-structure-changes-on-a-static-site</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/attitudes-to-reading-and-how-mine-have-changed</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/a-reflection-on-wintering-by-katherine-may</loc><priority>0.6</priority></url>
|
||||
<url><loc>https://www.aaronjy.me/writing/how-my-adhd-makes-handling-relationships-difficult</loc><priority>0.6</priority></url>
|
||||
</urlset>
|
3
src/components/Loading/Loading.jsx
Normal file
3
src/components/Loading/Loading.jsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function Loading() {
|
||||
return <p>Loading...</p>;
|
||||
}
|
|
@ -1,16 +1,35 @@
|
|||
import {
|
||||
FailedFetchBasicPageError,
|
||||
FailedFetchBasicPagesError,
|
||||
} from "@/errors";
|
||||
import Loading from "@/components/Loading/Loading";
|
||||
import { FailedFetchBasicPagesError } from "@/errors";
|
||||
import DefaultLayout from "@/layouts/DefaultLayout/DefaultLayout";
|
||||
import { mdxComponents } from "@/lib/mdx-components";
|
||||
import { fetchBasicPages } from "@/services/content-service";
|
||||
import { MDXClient } from "next-mdx-remote-client";
|
||||
import { serialize } from "next-mdx-remote-client/serialize";
|
||||
import { NextSeo } from "next-seo";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
export async function getServerSideProps({ params }) {
|
||||
export async function getStaticPaths() {
|
||||
const res = await fetchBasicPages(["path"]);
|
||||
|
||||
if (!res.ok) {
|
||||
throw new FailedFetchBasicPagesError(await res.text());
|
||||
}
|
||||
|
||||
const pages = (await res.json()).data;
|
||||
|
||||
return {
|
||||
paths: pages.map((page) => ({
|
||||
params: {
|
||||
path: [page.path ?? ""],
|
||||
},
|
||||
})),
|
||||
fallback: true,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const { path } = params;
|
||||
|
||||
const res = await fetchBasicPages([], {
|
||||
path: {
|
||||
_eq: path?.join("/") ?? null,
|
||||
|
@ -26,6 +45,7 @@ export async function getServerSideProps({ params }) {
|
|||
if (!page) {
|
||||
return {
|
||||
notFound: true,
|
||||
revalidate: 60,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -37,10 +57,21 @@ export async function getServerSideProps({ params }) {
|
|||
title,
|
||||
mdxSource,
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
}
|
||||
|
||||
export default function BasicPage({ title, mdxSource }) {
|
||||
const { isFallback } = useRouter();
|
||||
|
||||
if (isFallback) {
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<Loading />
|
||||
</DefaultLayout>
|
||||
);
|
||||
}
|
||||
|
||||
if (!mdxSource || "error" in mdxSource) {
|
||||
return <p>Something went wrong: {mdxSource?.error ?? "???"}</p>;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import { FailedFetchCVError } from "@/errors";
|
|||
|
||||
export const Title = "CV";
|
||||
|
||||
export async function getServerSideProps() {
|
||||
export async function getStaticProps() {
|
||||
const res = await fetchCV([]);
|
||||
|
||||
if (!res.ok) {
|
||||
|
@ -18,6 +18,7 @@ export async function getServerSideProps() {
|
|||
if (!cv) {
|
||||
return {
|
||||
notFound: true,
|
||||
revalidate: 60,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -31,6 +32,7 @@ export async function getServerSideProps() {
|
|||
certifications,
|
||||
experience,
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,37 +6,33 @@ import {
|
|||
FailedFetchBookReviewError,
|
||||
FailedFetchBookReviewsError,
|
||||
} from "@/errors";
|
||||
import { useRouter } from "next/router";
|
||||
import Loading from "@/components/Loading/Loading";
|
||||
|
||||
// export async function getStaticPaths () {
|
||||
// const res = await fetchBookReviews(['slug'], {
|
||||
// status: 'published'
|
||||
// })
|
||||
export async function getStaticPaths() {
|
||||
const res = await fetchBookReviews(["slug"], {
|
||||
status: "published",
|
||||
});
|
||||
|
||||
// if (!res.ok) {
|
||||
// throw new FailedFetchBookReviewsError(await res.text())
|
||||
// }
|
||||
|
||||
// const reviews = (await res.json()).data
|
||||
|
||||
// return {
|
||||
// paths: reviews.map(post => ({
|
||||
// params: {
|
||||
// slug: post.slug
|
||||
// }
|
||||
// })),
|
||||
// fallback: false // false or "blocking"
|
||||
// }
|
||||
// }
|
||||
|
||||
export const getServerSideProps = async ({ params }) => {
|
||||
const { slug } = params;
|
||||
|
||||
if (!slug) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
if (!res.ok) {
|
||||
throw new FailedFetchBookReviewsError(await res.text());
|
||||
}
|
||||
|
||||
const reviews = (await res.json()).data;
|
||||
|
||||
return {
|
||||
paths: reviews.map((post) => ({
|
||||
params: {
|
||||
slug: post.slug,
|
||||
},
|
||||
})),
|
||||
fallback: true,
|
||||
};
|
||||
}
|
||||
|
||||
export const getStaticProps = async ({ params }) => {
|
||||
const { slug } = params;
|
||||
|
||||
const res = await fetchBookReviews([], {
|
||||
slug,
|
||||
status: "published",
|
||||
|
@ -50,6 +46,7 @@ export const getServerSideProps = async ({ params }) => {
|
|||
if (!review) {
|
||||
return {
|
||||
notFound: true,
|
||||
revalidate: 60,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -61,13 +58,17 @@ export const getServerSideProps = async ({ params }) => {
|
|||
review,
|
||||
html,
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
};
|
||||
|
||||
export default function LibrarySingle({ review, html }) {
|
||||
const { isFallback } = useRouter();
|
||||
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<BookReview review={review} html={html} />
|
||||
{!isFallback && <BookReview review={review} html={html} />}
|
||||
{isFallback && <Loading />}
|
||||
</DefaultLayout>
|
||||
);
|
||||
}
|
||||
|
|
29
src/pages/server-sitemap-index.xml/index.jsx
Normal file
29
src/pages/server-sitemap-index.xml/index.jsx
Normal file
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
fetchBasicPages,
|
||||
fetchBookReviews,
|
||||
fetchPosts,
|
||||
} from "@/services/content-service";
|
||||
import { getServerSideSitemapIndexLegacy } from "next-sitemap";
|
||||
|
||||
const siteUrl = process.env.SITE_URL || "https://www.aaronjy.me";
|
||||
|
||||
export const getServerSideProps = async (ctx) => {
|
||||
const [basicPagesResp, bookReviewsResp, postsResp] = await Promise.all([
|
||||
fetchBasicPages().then((res) => res.json()),
|
||||
fetchBookReviews().then((res) => res.json()),
|
||||
fetchPosts().then((res) => res.json()),
|
||||
]);
|
||||
|
||||
const urls = [
|
||||
...basicPagesResp.data.map((entry) => `${siteUrl}/${entry.path ?? ""}`),
|
||||
...bookReviewsResp.data.map(
|
||||
(entry) => `${siteUrl}/library/${entry.slug ?? ""}`,
|
||||
),
|
||||
...postsResp.data.map((entry) => `${siteUrl}/writing/${entry.slug ?? ""}`),
|
||||
];
|
||||
|
||||
return getServerSideSitemapIndexLegacy(ctx, [...urls]);
|
||||
};
|
||||
|
||||
// Default export to prevent next.js errors
|
||||
export default function SitemapIndex() {}
|
|
@ -3,8 +3,31 @@ import DefaultLayout from "@/layouts/DefaultLayout/DefaultLayout";
|
|||
import Article from "@/components/Article/Article";
|
||||
import { fetchPosts, markdownToHtml } from "@/services/content-service";
|
||||
import { FailedFetchPostError, FailedFetchPostsError } from "@/errors";
|
||||
import { useRouter } from "next/router";
|
||||
import Loading from "@/components/Loading/Loading";
|
||||
|
||||
export const getServerSideProps = async ({ params }) => {
|
||||
export async function getStaticPaths() {
|
||||
const res = await fetchPosts(["slug"], {
|
||||
status: "published",
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new FailedFetchPostsError(await res.text());
|
||||
}
|
||||
|
||||
const posts = (await res.json()).data;
|
||||
|
||||
return {
|
||||
paths: posts.map((post) => ({
|
||||
params: {
|
||||
slug: post.slug,
|
||||
},
|
||||
})),
|
||||
fallback: true,
|
||||
};
|
||||
}
|
||||
|
||||
export const getStaticProps = async ({ params }) => {
|
||||
const { slug } = params;
|
||||
const res = await fetchPosts([], {
|
||||
slug,
|
||||
|
@ -19,6 +42,7 @@ export const getServerSideProps = async ({ params }) => {
|
|||
if (!post) {
|
||||
return {
|
||||
notFound: true,
|
||||
revalidate: 60,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,13 +54,17 @@ export const getServerSideProps = async ({ params }) => {
|
|||
post,
|
||||
html,
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
};
|
||||
|
||||
export default function WritingSingle({ post, html }) {
|
||||
const { isFallback } = useRouter();
|
||||
|
||||
return (
|
||||
<DefaultLayout>
|
||||
<Article {...post} html={html} />
|
||||
{!isFallback && <Article {...post} html={html} />}
|
||||
{isFallback && <Loading />}
|
||||
</DefaultLayout>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue