\section{Why Vercel + FormaTeX}
PDF generation without leaving your Next.js stack
Vercel functions can't run TeX Live — but they can make HTTP requests. The FormaTeX API turns a single fetch call into a fully compiled PDF.
Zero config deployment
Add one API route file and one environment variable. Push to Vercel — your PDF endpoint is live globally within seconds.
Works with App Router
The route handler follows the Next.js App Router convention. Export runtime, maxDuration, and the POST handler — that is all.
Streaming response
Pipe the upstream PDF bytes directly back to the browser without buffering the entire file in memory, keeping your function invocation fast and cost-efficient.
\section{Next.js API route}
The complete API route
Create app/api/pdf/route.ts in your Next.js project. The route accepts a POST with a JSON body containing source and an optional engine, then streams the compiled PDF back to the caller.
// app/api/pdf/route.ts
import type { NextRequest } from "next/server"
// Use the Node.js runtime — the Edge runtime does not support
// the full fetch API response streaming needed for binary files.
export const runtime = "nodejs"
// Vercel Hobby: 10 s max. Pro / Enterprise: up to 300 s.
// Set this to at least 30 s to handle complex documents.
export const maxDuration = 30
export async function POST(request: NextRequest) {
const body = await request.json()
const source: string = body.source ?? ""
const engine: string = body.engine ?? "pdflatex"
if (!source) {
return Response.json({ error: "source is required" }, { status: 400 })
}
const apiKey = process.env.FORMATEX_API_KEY
if (!apiKey) {
return Response.json({ error: "FORMATEX_API_KEY is not configured" }, { status: 500 })
}
const upstream = await fetch("https://api.formatex.io/v1/compile/sync", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ source, engine }),
})
if (!upstream.ok) {
const err = await upstream.json().catch(() => ({ error: "compilation failed" }))
return Response.json(err, { status: upstream.status })
}
// Stream the PDF bytes directly to the client — no buffering in memory.
return new Response(upstream.body, {
headers: {
"Content-Type": "application/pdf",
"Content-Disposition": 'attachment; filename="document.pdf"',
},
})
}\subsection{Calling the route}
Call /api/pdf from any client component or server action. The helper below triggers a browser download directly from the blob.
// Calling the route from a React component or server action
async function generatePdf(latexSource: string): Promise<void> {
const res = await fetch("/api/pdf", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ source: latexSource, engine: "pdflatex" }),
})
if (!res.ok) {
const { error } = await res.json()
throw new Error(error ?? "PDF generation failed")
}
// Trigger a browser download
const blob = await res.blob()
const url = URL.createObjectURL(blob)
const a = document.createElement("a")
a.href = url
a.download = "document.pdf"
a.click()
URL.revokeObjectURL(url)
}\section{Environment variables}
Adding your API key to Vercel
Open your project settings
Navigate to vercel.com → your project → Settings → Environment Variables.
Add FORMATEX_API_KEY
Set the name to FORMATEX_API_KEY and paste your key from the FormaTeX dashboard. Select Production (and optionally Preview) environments.
Redeploy
Environment variable changes take effect on the next deployment. Trigger a redeploy from the Vercel dashboard or by pushing a new commit.
Never expose FORMATEX_API_KEY to the browser. The variable is only accessible server-side inside a Route Handler or Server Action — it will not be included in the client bundle.
\section{Runtime selection}
Edge vs Node.js runtime
Edge runtime
Not recommended- 50 ms CPU limit — insufficient for complex documents
- 4 MB response body limit — may truncate large PDFs
- No Node.js built-ins like Buffer
Node.js runtime
Recommended- Up to 300 s execution (Pro/Enterprise plan)
- Full streaming response body support
- Standard Node.js Buffer and crypto available
Set export const runtime = "nodejs" at the top of your route file. Without it, Next.js may default to the Edge runtime on Vercel and PDF streaming will fail for large documents.
\section{Related guides}
More guides for your stack
The FormaTeX API is a plain HTTP endpoint. Reach it from any language or platform.

