refactor: centralize feed handler creation, use typed route props

This commit is contained in:
jake committed 2026-10-01 18:14:25 -04:00
1 parent 541489dfc9
commit f110c3aa04
6 files changed
+28 -31

No files matched your search

+2 -12
View File
@@ -1,13 +1,3 @@
import { NextResponse } from "next/server";
import { createFeedHandler } from "@/lib/build-feed";
import { buildFeed } from "@/lib/build-feed";
export const GET = () => {
const feed = buildFeed();
return new NextResponse(feed.atom1(), {
headers: {
"content-type": "application/atom+xml; charset=utf-8",
},
});
};
export const { GET } = createFeedHandler("atom");
+2 -12
View File
@@ -1,13 +1,3 @@
import { NextResponse } from "next/server";
import { createFeedHandler } from "@/lib/build-feed";
import { buildFeed } from "@/lib/build-feed";
export const GET = () => {
const feed = buildFeed();
return new NextResponse(feed.rss2(), {
headers: {
"content-type": "application/rss+xml; charset=utf-8",
},
});
};
export const { GET } = createFeedHandler("rss");
+1 -1
View File
@@ -16,7 +16,7 @@ import "./globals.css";
export const metadata = defaultMetadata;
const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => (
const RootLayout = ({ children }: LayoutProps<"/">) => (
<html
lang={process.env.NEXT_PUBLIC_SITE_LOCALE}
className={cn(SchibstedGrotesk.variable, JetBrainsMono.variable)}
+1 -1
View File
@@ -67,7 +67,7 @@ export const generateStaticParams = () =>
slug,
}));
const OpenGraphImage = async ({ params }: { params: Promise<{ slug: string }> }) => {
const OpenGraphImage = async ({ params }: PageProps<"/notes/[slug]">) => {
const { slug } = await params;
const frontmatter = getFrontMatter(slug);
if (!frontmatter) notFound();
+2 -4
View File
@@ -31,9 +31,7 @@ export const generateStaticParams = () => {
export const generateMetadata = async ({
params,
}: {
params: Promise<{ slug: string }>;
}): Promise<Metadata> => {
}: PageProps<"/notes/[slug]">): Promise<Metadata> => {
const { slug } = await params;
const frontmatter = getFrontMatter(slug);
@@ -54,7 +52,7 @@ export const generateMetadata = async ({
});
};
const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
const Page = async ({ params }: PageProps<"/notes/[slug]">) => {
const { slug } = await params;
const post = getPost(slug);
if (!post) notFound();
+20 -1
View File
@@ -1,4 +1,5 @@
import { Feed, type Item as FeedItem } from "feed";
import { NextResponse, type NextRequest } from "next/server";
import ogImage from "@/app/opengraph-image.jpg";
import authorConfig from "@/lib/config/author";
@@ -9,7 +10,7 @@ import { getPost, getFrontMatter } from "@/lib/posts";
* Returns a `Feed` object, which can then be processed with `feed.rss2()`, `feed.atom1()`, or `feed.json1()`.
* @see https://github.com/jpmonette/feed#example
*/
export const buildFeed = (): Feed => {
const buildFeed = (): Feed => {
const frontmatter = getFrontMatter();
const feed = new Feed({
@@ -60,3 +61,21 @@ export const buildFeed = (): Feed => {
return feed;
};
export const createFeedHandler = (
feedType: "rss" | "atom" | "json",
): { GET: (request: NextRequest) => Promise<Response> } => {
return {
GET: async () => {
const feed = buildFeed();
return new NextResponse(
feed[feedType === "rss" ? "rss2" : feedType === "atom" ? "atom1" : "json1"](),
{
headers: {
"content-type": `application/${feedType}+xml; charset=utf-8`,
},
},
);
},
};
};