Route Handlers can return a plain Response, not just NextResponse
TIL you don't need NextResponse for a simple Route Handler — a standard Web API Response works fine, which matters for things like hand-rolled RSS/XML endpoints.
Today I learned that an App Router Route Handler doesn't require NextResponse — a plain, standard Response works fine for anything that doesn't need Next-specific extras (cookies helpers, rewrites, etc.).
export function GET() {
const xml = `<?xml version="1.0"?><rss>...</rss>`;
return new Response(xml, {
headers: { "Content-Type": "application/xml; charset=utf-8" },
});
}This is obvious in hindsight — Route Handlers are built on the Web platform's Request/Response primitives, and NextResponse is just a convenience subclass — but I'd been reaching for NextResponse.json() out of habit even for a hand-rolled XML feed, where it doesn't add anything.
NextResponse earns its keep when you need .cookies, .rewrite(), or .redirect(). For a static XML/plain-text response like an RSS feed, a bare Response is one less import.
Related content
A mental model for Server vs Client Components
The rule of thumb I actually use when deciding whether a component needs 'use client', and how a Server Component parent can still pass data down to it.
A JSX expression-container attribute silently loses its value in next-mdx-remote
TIL that generating attr={"..."} into MDX source instead of attr="..." made a prop come back as an empty object on every render, with no error anywhere in the pipeline — found while writing the Obsidian-callout preprocessor for this site.
Auth Context for Next.js (Cookie-Based Sessions)
A React context wrapping an API — login, logout, signup, and password reset — that keeps the client in sync with an httpOnly session cookie by revalidating on mount.