イメージとしては、MDやMDXと同様に、PDFも置いたらそのままURLになってほしいというもの。
そんな機能はない
はず。
少なくとも、MDやMDXのような一級のサポートはない。
なので、
/public
にPDFファイルを置くgetStaticPaths()
でそのファイルを探す- 個別ルートでは、単にリダイレクトするか、
fetch()
して横流しする
ということになりがち。
だが、/public
はカオスになりがちなので、あまりやりたくない。
ワークアラウンド
問題は、元ソースとして扱うPDFをいかにしてビルド後のアウトプットに持っていくか。dist/_astro
にいかにして持っていくか。
というわけで、[id].pdf.ts
というファイル名で、エンドポイントを立てて、自力でビルドする。
import { readdir, readFile } from "node:fs/promises";
import type { APIRoute } from "astro";
const PDF_DIR = "./path/to/pdf";
export async function getStaticPaths() {
const events = await readdir(PDF_DIR);
return events.map((id) => ({
params: { id },
props: {},
}));
}
// ---
export const GET: APIRoute = async ({ params: { id } }) => {
const pdfPath = `${PDF_DIR}/${id}`;
let pdfBuf;
try {
pdfBuf = await readFile(pdfPath);
} catch (cause) {
throw new Error(`Failed to read ${pdfPath}`, { cause });
}
return new Response(pdfBuf, {
headers: {
"Content-Type": "application/pdf",
"Content-Disposition": `inline; filename="${id}"`,
"Content-Length": pdfBuf.length.toString(),
},
});
};
ビルド時にPDFを読んで、それをそのまま吐き出してるので、やや処理としては無駄があるけど、やりたいことはできた。