Skip to Content
Manual Install

Manual install

Create Next.js project with App Router and TypeScript

Follow the official Next.js guideΒ  to install Next.js. Use TypeScript, App Router and src/ directory.

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

Install β€œvovk” and β€œvovk-client”

npm i vovk vovk-client

Create an empty config file (optional)

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

vovk.config.mjs
// @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:

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

Read more about validation.

Update β€œdev” and β€œbuild” 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 to run Next.js server by itself. At this case vovk-cli will assign the port automatically.

The build script will run vovk generate before next build in order to generate the client library before building the Next.js app.

Install concurrently:

npm i -D concurrently

Update the β€œdev” script in package.json:

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

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.

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!' }; } }

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).

At the code below HelloRPC indicates the name of the exported client library and HelloController is the controller class 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 });

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.

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 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 need to restart the TS server manually.

Last updated on