Skip to main content

Framework Guide: App Router

@markpdf/nextjs covers the two common App Router patterns for exposing document conversion to your UI: Route Handlers (when you want your own HTTP endpoint, for example to call it from fetch on the client or from another service) and Server Actions (when the form and server logic live in the same file, without defining a route).

Rule of thumb: the API key never leaves the server

The entire package assumes that it is imported only from:
  • Route Handlers (app/**/route.ts)
  • Server Actions ("use server")
  • Server Components
If you import @markpdf/nextjs from a Client Component ("use client"), the bundler will fail or, worse, the final bundle would end up needing the key in the browser. The package is intended not to work outside of the Next.js server environment.

Route Handler: createConvertRouteHandler

app/api/convert/route.ts
string
required
Your API key. Always read it from process.env, never hardcode it.
ConvertOptions
number
Own limit before forwarding to API — useful for cutting huge uploads at the edge of your app without spending API quota.
The generated handler:
  1. Parse multipart/form-data of Request.
  2. Forward the file to POST /convert/raw with @markpdf/sdk.
  3. Returns the response for API as is (Markdown or JSON), including the correct content-type.
  4. Translate errors from SDK (MarkpdfAuthError, MarkpdfPayloadTooLargeError, etc.) to HTTP responses with the same status code.

Customize the handler

If you need extra logic (auth of your own app, logging, your own rate limiting), use the client directly instead of the all-in-one helper:
app/api/convert/route.ts

Server Action: convertFormData y convertUrlAction

app/actions.ts
Server Actions behave like normal Node functions from the client’s point of view — Next.js serializes the call for you. You don’t need to expose any routes.
Use Server Actions when the upload form lives in the same component that triggers the conversion (minus boilerplate). Use a Route Handler when another service, a webhook, or a client other than your Next.js app needs to call the endpoint directly.

Streaming in a Route Handler

app/api/convert/stream/route.ts
Next.js forwards ReadableStream back to the client without buffering, so the client starts receiving Markdown before the conversion finishes. See Streaming and async.

Runtime: Node vs Edge

@markpdf/nextjs works in both Next.js runtimes:
app/api/convert/route.ts
For large uploads (PDFs of tens of MB) use runtime = "nodejs". The Next.js edge runtime has lower request size limits that depend on your hosting provider.