Skip to Content
Manual Install

Manual Install

Create a Next.js project (App Router + TypeScript)

npx create-next-app my-app --ts --app --src-dir
cd my-app

The src directory is optional but recommended because it keeps the project root clean.

Install vovk and vovk-client

npm i vovk vovk-client

More info:

Create the config file

Create vovk.config.mjs at the project root with the following content:

vovk.config.mjs
// @ts-check /** @type {import('vovk').VovkConfig} */ const vovkConfig = {}; export default vovkConfig;

More info:

Install a validation library and enable client-side validation

For Zod validation on the server and Ajv on the client, install:

npm i zod vovk-zod vovk-ajv

Configure validateOnClient in your config file to enable client-side validation:

vovk.config.mjs
// @ts-check /** @type {import('vovk').VovkConfig} */ const vovkConfig = { outputConfig: { imports: { validateOnClient: 'vovk-ajv', }, }, }; export default vovkConfig;

More info:

Update the dev script and add a prebuild script

There are two ways to run Vovk.ts and the Next.js server together: explicitly and implicitly. The explicit option uses the concurrently package to run both processes (you must set PORT). The implicit option lets the Vovk.ts CLI start Next.js for you; in that case, vovk-cli assigns the port automatically.

The prebuild script runs vovk generate before next build so the client library is generated ahead of the Next.js build.

Install concurrently:

npm i -D concurrently

Update the “dev” script in package.json:

"scripts": { "build": "next build", "dev": "PORT=3000 concurrently 'vovk dev' 'next dev' --kill-others", "prebuild": "vovk generate" }

More info:

Enable decorators

In your tsconfig.json, set "experimentalDecorators" to true.

{ "compilerOptions": { "experimentalDecorators": true // ... } }

Create a controller

Create HelloController.ts in /src/modules/hello/ with a class of the same name.

src/modules/hello/HelloController.ts
import { get, prefix } from 'vovk'; @prefix('greetings') // prefix is optional export default class HelloController { @get('greeting') static getHello() { return { greeting: 'Hello, World!' }; } }

More info:

Create a root segment

Create the root segment /src/app/api/[[…vovk]]/route.ts, where [[…vovk]] is an “Optional Catch-all Segment” . The slug can be any valid name, such as [[…mySlug]].

In the code below, HelloRPC is the name of the generated RPC module, and HelloController is the controller created above.

src/app/api/[[...vovk]]/route.ts
import { initSegment } from 'vovk'; import HelloController from '../../../modules/hello/HelloController'; const controllers = { HelloRPC: HelloController }; // export types that are inferred by the client export type Controllers = typeof controllers; // export Next.js route handlers export const { GET, POST, PUT, DELETE } = initSegment({ controllers });

More info:

Run the dev server

Run npm run dev to start Vovk.ts and Next.js concurrently.

npm run dev

Navigate to http://localhost:3000/api/greetings/greeting  to see the result.

Create a React component

Once the client is generated, you can import it from vovk-client.

src/app/page.tsx
'use client'; import { useState } from 'react'; import { HelloRPC } from 'vovk-client'; import type { VovkReturnType } from 'vovk'; export default function MyComponent() { const [serverResponse, setServerResponse] = useState<VovkReturnType<typeof HelloRPC.getHello>>(); return ( <> <button onClick={async () => { const response = await HelloRPC.getHello(); setServerResponse(response); }} > Get Greeting from Server </button> <div>{serverResponse?.greeting}</div> </> ); }

Open http://localhost:3000  to see the result.

ℹ️

If you’re using VSCode, you may need to restart the TS server when you add a new controller class. This is the only time a manual restart is typically required; other changes—like adding methods or updating validation—are picked up automatically.

More info:

Last updated on