Manual install
Create Next.js project with App Router and TypeScript
npx create-next-app my-app --ts --app --src-dir
cd my-app
src
dir is optional but recommended, as it keeps the root directory clean.
Install “vovk” and “vovk-client”
npm i vovk vovk-client
Create an empty config file (optional)
Create vovk.config.mjs at the root of the project with the following content:
// @ts-check
/** @type {import('vovk').VovkConfig} */
const vovkConfig = {};
export default vovkConfig;
Install validation library and enable client validation
For Zod validation on server-side and Ajv on client-side you can install the following packages:
npm i vovk-zod vovk-ajv
Modify validateOnClient
import at your config file to enable client-side validation:
// @ts-check
/** @type {import('vovk').VovkConfig} */
const vovkConfig = {
generatorConfig: {
imports: {
validateOnClient: 'vovk-ajv',
},
},
};
export default vovkConfig;
Update “dev” and create “prebuild” NPM scripts
There are two ways to run Vovk.ts and Next.js server concurrently: explicitly and implicitly. The explicit way is to install concurrently
package and run both scripts with it, this requires PORT
variable to be set. The implicit way is to make Vovk.ts CLI to run Next.js server by itself. At this case vovk-cli will assign the port automatically.
The prebuild
script will run vovk generate
before next build
in order to generate the client library before building the Next.js app.
Explicit
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"
}
Enable decorators
In your tsconfig.json set "experimentalDecorators"
to true
.
{
"compilerOptions": {
"experimentalDecorators": true
// ...
}
}
Create controller
Create HelloController.ts at /src/modules/hello/ with same-named static class.
import { get, prefix } from 'vovk';
@prefix('greetings') // prefix is optional
export default class HelloController {
@get('greeting')
static getHello() {
return { greeting: 'Hello, World!' };
}
}
Create root segment
Create the root segment /src/app/api/[[…vovk]]/route.ts where [[…vovk]] is a folder name indicating what Next.js documentation calls “Optional Catch-all Segment” (the slug can be any valid slug, such as
At the code below HelloRPC
indicates the name of the generated RPC module and HelloController
is the controller module 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 });
Run “vovk dev”
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
Now the client is generated you can safely import your client library 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 HelloController.getHello>>();
return (
<>
<button
onClick={async () => {
const response = await HelloController.getHello();
setServerResponse(response);
}}
>
Get Greeting from Server
</button>
<div>{serverResponse?.greeting}</div>
</>
);
}
Open http://localhost:3000 and see the result.
Note that if you’re using VSCode you’re probably going to need to restart TS
server each time when you add a new
controller class to your app. Changing the controller
list is the only case when you may need to restart the TS server
manually, other changes such as adding new methods or changing validation will be picked up automatically.