---
url: /httpx.zig/web/documentation-ui.md
---
# Interactive Documentation UIs

HTTPX bundles and serves modern, interactive API documentation user interfaces directly from your server without requiring Node.js or external CDNs: **Swagger UI**, **ReDoc**, **Scalar**, and **GraphiQL**.

## Single Source of Truth

All three REST documentation UIs consume the exact same canonical OpenAPI 3.1.0 specification generated by `server.openapi()`.

```text
Server Routes + Schema Reflection
               │
               ▼
   /openapi.json (OpenAPI 3.1.0)
   ┌───────────┼───────────┐
   ▼           ▼           ▼
Swagger UI   ReDoc       Scalar
 (/docs)    (/redoc)    (/scalar)
```

## Mounting Documentation UIs

Documentation routes mount automatically from `Server` config (or manually via
`httpx.docs.mount`). All UIs consume the same canonical `/openapi.json`:

```zig
const std = @import("std");
const httpx = @import("httpx");

pub fn main() !void {
    var gpa: std.heap.DebugAllocator(.{}) = .init;
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
    const io = std.Io.Threaded.global_single_threaded.io();

    var server = try httpx.Server.init(allocator, io, .{
        .port = 8080,
        .enableDocs = true,
        .docs = .{
            .title = "Store API",
            .version = "1.0.0",
            .description = "Production e-commerce API built with HTTPX",
            .swagger = .{ .enabled = true, .route = "/docs", .title = "Store API - Swagger" },
            .redoc = .{ .enabled = true, .route = "/redoc", .title = "Store API - ReDoc" },
            .scalar = .{ .enabled = true, .route = "/scalar", .title = "Store API - Scalar" },
            .graphiql = .{ .enabled = true, .route = "/graphiql", .graphqlEndpoint = "/graphql", .title = "Store API - GraphiQL" },
        },
    });
    defer server.deinit();

    server.run();
}
```

For router-only setups (no `Server`), mount explicitly:

```zig
try httpx.docs.mount(allocator, &router, .{ .title = "Store API" }, null);
```

## Enabling and Disabling Docs

`enableDocs` is the global switch for all documentation. Each UI is
individually optional — every option below defaults to enabled:

```zig
var server = try httpx.Server.init(allocator, io, .{
    .enableDocs = true, // global switch; false disables everything
    .docs = .{
        .openapi = .{ .enabled = true },   // /openapi.json
        .swagger = .{ .enabled = false },  // hide Swagger UI
        .redoc = .{ .enabled = true },     // keep ReDoc
        .scalar = .{ .enabled = true },    // keep Scalar
        .graphiql = .{ .enabled = false }, // hide GraphiQL
    },
});
```

Each section also takes its own `route` and `title`. Disabled routes are
never registered, so they return 404 like any unknown path.

## Features per UI

* **Swagger UI** (`/docs`): Interactive parameter inputs, schema inspection, and live "Try It Out" test requests against the server.
* **ReDoc** (`/redoc`): Elegant three-panel layout featuring sticky table of contents, code samples, and nested schema browsing.
* **Scalar** (`/scalar`): Next-generation developer portal with integrated dark mode, multi-language client SDK generation, and instant search.
* **GraphiQL** (`/graphiql`): Full GraphQL explorer with auto-completion, inline docs introspection, query history, and variable editor.

## Related

* [Web: OpenAPI](/web/openapi)
* [Web: GraphQL](/web/graphql)
* [Example: Docs Server](/examples/docs-server)
