Manual Install
Create a Next.js project (App Router + TypeScript)
npx create-next-app my-app --ts --app --src-dircd my-appThe src directory is optional but recommended because it keeps the project root clean.
Install vovk and vovk-client
npm i vovk vovk-clientMore info:
Create the config file
Create vovk.config.mjs at the project root with the following content:
// @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-ajvConfigure validateOnClient in your config file to enable client-side validation:
// @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.
Explicit
Install concurrently:
npm i -D concurrentlyUpdate 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.
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
In the code below, HelloRPC is the name of the generated RPC module, and HelloController is the controller created above.
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 devNavigate 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.
'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: