FormaTeX

\usepackage{vercel}

LaTeX PDF generation on Vercel

Add a single Next.js API route to your Vercel project and generate PDFs from LaTeX on demand. No build configuration, no custom runtimes — one environment variable and you are live.

\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

1

Open your project settings

Navigate to vercel.com → your project → Settings → Environment Variables.

2

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.

3

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.

Ship LaTeX PDFs from your Vercel project today

Free tier — 15 API compilations per month. No credit card required.

One quick thing

We track anonymous usage — page views, feature usage, compilation events — to understand what works and what doesn't. No ads, no personal data, no third-party sharing.

Cookie policy