Skip to Content
SegmentStatic Segment

Static Segment

npx vovk new segment openapi --static # creates a new static segment named "openapi" at src/app/api/openapi/[[...vovk]]/route.ts

Next.js can pre-render API endpoints at build time using generateStaticParams . Vovk.ts provides the generateStaticAPI helper to take advantage of this and emit static API endpoints for minimal latency. Use it to serve OpenAPI definitions, historical datasets (refreshed periodically via CI/CD), or other infrequently changing data. It also works in Static Export mode  with the output: 'export' Next.js option:

next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = { output: 'export', }; module.exports = nextConfig;

All you need to do is implement generateStaticParams and return generateStaticAPI with your controller list.

src/app/api/[[...vovk]]/route.ts
// ... export type Controllers = typeof controllers; export function generateStaticParams() { return generateStaticAPI(controllers); } export const { GET } = initSegment({ controllers });

When deploying to static hosting (e.g., GitHub Pages), include a .json extension in endpoint paths to ensure proper HTTP headers are served.

import { get, prefix } from 'vovk'; @prefix('hello') export default class HelloController { @get('greeting.json') static async getHello() { return { greeting: 'Hello world!' }; } }

This produces an endpoint like: https://vovk.dev/api/hello/greeting.json  (hosted on GitHub Pages).

If you use a custom slug (e.g., /src/app/api/[[...custom]]/route.ts) instead of the default vovk, pass it as the second argument:

export function generateStaticParams() { return generateStaticAPI(controllers, 'custom'); }

Static Endpoint Parameters

The @get decorator accepts an options object. One of the options, staticParams, lets you enumerate static parameter combinations to simulate conditional routing. The example below shows a single handler that renders six variants for two parameters: section (a | b) and page (1 | 2 | 3).

import { z } from 'zod/v4'; import { prefix, get, operation } from 'vovk'; import { withZod } from 'vovk-zod'; @prefix('static-params') export default class StaticParamsController { @operation({ summary: 'Static Params', description: 'Get the static params: section and page', }) @get('{section}/page{page}.json', { staticParams: [ { section: 'a', page: '1' }, { section: 'a', page: '2' }, { section: 'a', page: '3' }, { section: 'b', page: '1' }, { section: 'b', page: '2' }, { section: 'b', page: '3' }, ], }) static getStaticParams = withZod({ params: z.object({ section: z.enum(['a', 'b']), page: z.enum(['1', '2', '3']), }), handle: async (_req, { section, page }) => { return { section, page }; }, }); }

This builds six JSON files:

See the live example here .

RPC Client

Whether the API is static or dynamic, you call it with the same RPC client, including client-side validation and type inference.

const resp = await StaticParamsRPC.getStaticParams({ params: { section: 'a', page: '1', }, }); console.log(resp); // { section: 'a', page: '1' }

Troubleshooting

When output: 'export' is set in next.config.js, running npm run dev may show a schema parsing error:

⨯ SyntaxError: Unexpected non-whitespace character after JSON at position 396 (line 1 column 397) at JSON.parse (<anonymous>) { page: '/api/_schema_' }

To avoid this during npm run dev, close any open app tabs until the initial request to /_schema_ completes. Then reopen the app. If the error persists, please open an issue on the Vovk.ts GitHub repository  with details.

Last updated on