Route handlers in a Next.js static export have to opt in
This site is output: "export", which means next build writes plain files
and there is no server afterwards. I wanted an RSS feed as a route handler
rather than a script that writes into public/, and the build refused until I
added one line.
Two rules, and the error message only really tells you about the first one.
A route handler in a static export must be a GET, and it must declare
itself static:
export const dynamic = "force-static";
export async function GET() {
// ...
}
Without force-static, the build treats the handler as dynamic and tells you
it cannot be exported. POST, PUT and friends have nowhere to run at all,
so they fail outright.
The second rule is the one that actually bites later: the handler runs exactly
once, during the build, and its response body is written to disk as a file.
Anything you compute inside it is frozen at that moment. new Date() in there
is the build time, not the request time. If you want the feed to change, you
rebuild.
The file path is the URL, extension included. src/app/feed.xml/route.ts
produces /feed.xml, which means you get a directory literally named
feed.xml in your source tree. It looks wrong in the file browser every
single time and it is correct.