pdf-raster

Next.js route handler example

The smallest correct Next.js server-side pattern for converting PDFs inside App Router.

Node runtime only

Keep this package in a Node.js route handler or other server-only code. Do not import it into the client or Edge runtime.

This page shows only the server route. If you also want a client upload form and a preview grid that renders every returned page image, use the full Next.js upload and preview example.

Example route handler

route.ts
import { NextResponse } from "next/server";
import { convert, PdfToImagesError } from "@omsimos/pdf-raster";

export const runtime = "nodejs";

export async function POST(request: Request) {
  try {
    const formData = await request.formData();
    const upload = formData.get("file");
    const isPdf =
      upload instanceof File &&
      (upload.type === "application/pdf" ||
        upload.name.toLowerCase().endsWith(".pdf"));

    if (!isPdf || !(upload instanceof File)) {
      return NextResponse.json(
        { code: "INVALID_INPUT", message: "Missing PDF upload." },
        { status: 400 },
      );
    }

    const bytes = Buffer.from(await upload.arrayBuffer());
    const pages = await convert(bytes, {
      pages: [0],
      outputFormat: "webp",
      dpi: 300,
    });

    return NextResponse.json({
      pages: pages.map((page) => ({
        pageIndex: page.pageIndex,
        width: page.width,
        height: page.height,
        dpi: page.dpi,
        mimeType: page.mimeType,
        src: `data:${page.mimeType};base64,${page.data.toString("base64")}`,
      })),
    });
  } catch (error) {
    if (error instanceof PdfToImagesError) {
      return NextResponse.json(
        { code: error.code, message: error.message },
        { status: 400 },
      );
    }

    return NextResponse.json(
      { code: "RENDER_ERROR", message: "Unexpected conversion failure." },
      { status: 500 },
    );
  }
}

This route shape is useful when:

  • your frontend is already built and only needs an API endpoint
  • you want to keep the native package isolated to one server route
  • you plan to return small preview payloads, object-storage URLs, or other app-specific response shapes

Why a route handler works well

  • keeps the native binding on the server
  • accepts uploads directly
  • can normalize errors into stable API responses
  • lets the client render previews without touching PDFium directly

Use data URLs for small previews

Returning data: URLs is convenient for demos and document previews. For larger jobs, it is usually better to return file handles, object-storage URLs, or another server-side reference instead of base64-encoding every page into JSON.

If you want to see the matching client page that uploads a PDF and renders the returned images, continue to the full Next.js upload and preview example.

On this page