# Documenting a Next.js API With OpenAPI and Swagger UI

> Serve an OpenAPI spec from a Next.js App Router route and render it with Swagger UI to get interactive API docs that stay in step with the code.

Canonical: https://mikereams.com/writing/next-js-with-swagger-3-setup

Published: December 28, 2022  
Author: Mike Reams (https://mikereams.com/about)  
Topics: [Web Development](https://mikereams.com/writing/topics/web-development), [API](https://mikereams.com/writing/topics/api), [Architecture](https://mikereams.com/writing/topics/architecture)  
Tags: swagger, openapi, nextjs, api  
Project: [Creative Social NFT Marketplace](https://mikereams.com/work/creative-social-nft-marketplace)

![Next.js With Swagger 3 Setup](https://mikereams.com/writing/cc8a666dd9889ed1b97e44f237558e1069d1f7b6-818x200.png)

*First written in 2022 while building the API for Creative Social; rewritten in 2026 for the current OpenAPI release and the Next.js App Router.*

## OpenAPI and Swagger, briefly

**OpenAPI** is a standard way to describe a REST API in YAML or JSON: its endpoints and operations, parameters and responses, authentication, and contact and license details. It used to be called the Swagger Specification.

**Swagger** is the family of open-source tools built around OpenAPI. The ones you'll reach for most:

- [Swagger Editor](https://editor.swagger.io/): write and validate a definition in the browser.
- [Swagger UI](https://github.com/swagger-api/swagger-ui): render a definition as interactive documentation where readers can try calls.
- [Swagger Codegen](https://github.com/swagger-api/swagger-codegen): generate server stubs and client libraries. [OpenAPI Generator](https://openapi-generator.tech/), a community fork, does the same job.

## Why describe your API this way

A spec is a contract that tools can read. With one in hand you can publish interactive docs, generate client SDKs and server stubs, import the API into testing tools, and review the design before anyone writes code. Design-first teams write the spec, then build to it.

## The shape of a spec

Start with the OpenAPI version and some metadata, then describe each path. Everything is case-sensitive.

```
openapi: 3.1.0
info:
  title: Sample API
  description: Optional. CommonMark is allowed.
  version: 0.1.9
paths:
  /users:
    get:
      summary: List users
      responses:
        "200":
          description: A JSON array of user names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
```

Which version to target: [3.2.0](https://spec.openapis.org/oas/v3.2.0.html) is the latest release (September 2025); 3.1 aligned schemas with JSON Schema; some tools still require 3.0. Use the newest version your whole tool chain supports — for most chains today, that's 3.1.

## Serving the spec and docs from Next.js

With the App Router, keep the spec as a file in the repo, serve it from a route handler, and render Swagger UI on its own page.

```
// app/api/openapi/route.ts
import spec from "@/openapi.json";

export function GET() {
  return Response.json(spec);
}
```

```
// app/api-docs/page.tsx
"use client";
import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";

export default function ApiDocs() {
  return <SwaggerUI url="/api/openapi" />;
}
```

- **swagger-ui-react is heavy** and runs in the browser. Keep it on the docs page only, so it never loads with the rest of the app.
- **Hand-written or generated?** A hand-written spec (design-first) reviews well. A spec generated from annotations in your route code, with a library such as next-swagger-doc (code-first), stays in step with the code. Pick one source of truth.
- **Public or not?** If the API isn't public, protect the docs page and the spec route, or leave them out of production builds.
