Last active
February 17, 2023 02:14
-
-
Save AndrewIngram/29cdb0c2cdb55e022dcdb6f44ee1ecce to your computer and use it in GitHub Desktop.
Next.js SItemap route with streaming (requires Node 18+)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { SitemapStream, EnumChangefreq } from "sitemap"; | |
import { getAllPosts } from "~/data"; | |
import { Readable } from "node:stream"; | |
async function* getSitemapUrls(request: Request) { | |
const url = new URL(request.url); | |
const origin = `${url.protocol}//${url.host}`; | |
const buildUrl = (path: string) => `${origin}${path}`; | |
yield { | |
url: buildUrl("/"), | |
changefreq: EnumChangefreq.DAILY, | |
priority: 0.7, | |
}; | |
for (const post of await getAllPosts()) { | |
yield { | |
url: buildUrl(`/posts/${post.slug}`), | |
changefreq: EnumChangefreq.DAILY, | |
priority: 0.7, | |
}; | |
} | |
} | |
export async function GET(request: Request) { | |
try { | |
const smStream = new SitemapStream(); | |
Readable.from(getSitemapUrls(request)).pipe(smStream); | |
// smStream is a node stream, so we need to turn it into a web platform one. | |
const reader = Readable.toWeb(smStream).getReader(); | |
const encoder = new TextEncoder(); | |
const stream = new ReadableStream({ | |
async pull(controller) { | |
const { value, done } = await reader.read(); | |
if (done) { | |
return controller.close(); | |
} | |
controller.enqueue(encoder.encode(value)); | |
}, | |
}); | |
return new Response(stream, { | |
headers: { | |
"Content-Type": "application/xml", | |
}, | |
status: 200, | |
}); | |
} catch (e) { | |
console.error(e); | |
return new Response("", { | |
status: 500, | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment