Deno Fresh で sitemap.xml を SSR する middleware
import { MiddlewareHandlerContext } from "$fresh/server.ts";
import { pool, selectPostIds, selectUsers } from "~/lib/db.ts";
export async function handler(
_req: Request,
ctx: MiddlewareHandlerContext,
) {
const resp = await ctx.next();
const url = new URL(_req.url);
if (url.pathname === "/sitemap.xml") {
const [users, posts] = await pool(async (client) => {
const users = await selectUsers(client);
const posts = await selectPostIds(client);
return [users, posts];
});
const baseUrl = `${url.protocol}//${url.hostname}${
url.hostname === "localhost" ? (":" + url.port) : ""
}`;
return new Response(
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">${
users.map((user) =>
`<url><loc>${baseUrl}/users/${user.user_id}</loc><lastmod>${
new Date(user.updated_at).toISOString()
}</lastmod></url>`
).join() + posts.map((post) =>
`<url><loc>${baseUrl}/posts/${post.id}</loc><lastmod>${
new Date(post.updated_at).toISOString()
}</lastmod></url>`
)
}</urlset>`,
{
headers: { "content-type": 'application/xml; charset="UTF-8"' },
},
);
}
return resp;
}
SSG するとか ISR するとか色々改善点は考えられる。
ReadableStream を使うようにするとか。