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:
// @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:
// @ts-check
/** @type {import('vovk').VovkConfig} */
const vovkConfig = {
imports: {
validateOnClient: 'vovk-ajv',
},
};
export default vovkConfig;
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.
Explicit
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.
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.
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 need to restart the TS server manually.