# Vue / Nuxt Video Conferencing App with the Zoom Video SDK The [Zoom Video SDK](/docs/video-sdk/) provides video, audio, screen sharing, chat, and more with an easy to use SDK. In this blog we'll showcase adding video chat to a Nuxt web application. If you're building a Vue application without Nuxt you can skip to [Build the Videocall Component](#step-5-build-the-videocall-component) section, and use your own backend logic to generate JWTs. You can find the code for this blog on [GitHub](https://github.com/zoom/VideoSDK-VueNuxt-Quickstart/). Prerequisites: - Node LTS & NPM - A Zoom [Video SDK Account](/docs/video-sdk/get-credentials/) ## Step 1: Scaffold the application If you already have a [Nuxt](https://nuxtjs.org/) project, you can skip this step. To scaffold our application we use [Nuxi](https://nuxt.com/docs/getting-started/installation#new-project) the Nuxt CLI. Open a terminal and execute: ```bash npx nuxi@latest init ``` You can use the package manager of your choice. ## Step 2: Configuring the project ### Install the dependencies We will install the [Zoom Video SDK](https://www.npmjs.com/package/@zoom/videosdk) and [jsrsasign](https://www.npmjs.com/package/jsrsasign) a library to generate JWTs. You can use the following command for installation: ```bash npm install @zoom/videosdk jsrsasign ``` ### Enable shared array buffers To leverage the full power of the Zoom Video SDK including features like rendering multiple videos, virtual background, & background noise suppression, we need to enable support for Shared Array Buffers (SAB) in the browser. Simply, download this [file](https://github.com/gzuidhof/coi-serviceworker/blob/master/coi-serviceworker.js) and place it in the `public` folder of your project as `public/coi-serviceworker.js`. Later we'll import this file to enable SAB support. You can read more about SAB [in our documentation](/docs/meeting-sdk/web/sharedarraybuffer/). ### Add environment variables To complete the setup, create a `.env` file in the root of our project and add the Zoom Video SDK Key and Secret to it. You can find your SDK Key and Secret in the [Video SDK Dashboard](https://marketplace.zoom.us), by clicking on the _Develop_ button and selecting _Build Video SDK_. Make sure you're logged in to your Video SDK account. ```bash ZOOM_SDK_KEY="Your Zoom SDK Key" ZOOM_SDK_SECRET="Your Zoom SDK Secret" ``` ### Nuxt config We'll add the environment variable to the `runtimeConfig` in `nuxt.config.ts` allowing us to access these directly in our application later. ```js export default defineNuxtConfig({ runtimeConfig: { ZoomVideoSDKKey: process.env.ZOOM_SDK_KEY, ZoomVideoSDKSecret: process.env.ZOOM_SDK_SECRET, }, ``` We'll set `compilerOptions` to allow for the `video-player-container` custom element that we'll use with the Zoom Video SDK. ```js ... vue: { compilerOptions: { isCustomElement: (tag) => tag === 'video-player-container' } }, ``` We'll add the `coi-serviceworker.js` script to the `app.head.script` array to import it in our application. We'll also set the `css` property to include our custom CSS file. ```js ... app: { head: { script: [ { src: 'coi-serviceworker.js', } ], } }, css: ['~/assets/css/main.css'], }) ``` ## Step 3: Authenticate a session The Zoom Video SDK uses JWTs to authenticate a session. We can define an API route in `/server/api/token.ts` to generate a JWT based on the session slug. Creating a JWT requires the SDK Key and Secret. We'll execute this function only on the server, keeping our SDK key and secret secure. This will create a JWT using the `generateSignature` function and return it. ```js export default defineEventHandler(async (event) => { const query = getQuery(event); console.log(typeof query.slug); if (typeof query.slug !== "string") { throw createError({ statusCode: 400, statusMessage: "Add a session name as string", }); } const JWT = await generateSignature(query.slug, 1); return JWT; }); ``` The `generateSignature` function will use the `jsrsasign` library and the session name to generate the JWT: ```js import { KJUR } from "jsrsasign"; function generateSignature(sessionName: string, role: number) { const runtimeConfig = useRuntimeConfig(); const sdkKey = runtimeConfig.ZoomVideoSDKKey; const sdkSecret = runtimeConfig.ZoomVideoSDKSecret; if (!sdkKey || !sdkSecret) { throw new Error("Missing ZOOM_SDK_KEY or ZOOM_SDK_SECRET"); } const iat = Math.round(new Date().getTime() / 1000) - 30; const exp = iat + 60 * 60 * 2; const oHeader = { alg: "HS256", typ: "JWT" }; const oPayload = { app_key: sdkKey, tpc: sessionName, role_type: role, version: 1, iat: iat, exp: exp, }; const sHeader = JSON.stringify(oHeader); const sPayload = JSON.stringify(oPayload); const sdkJWT = KJUR.jws.JWS.sign("HS256", sHeader, sPayload, sdkSecret); return sdkJWT; } ``` We can access the `ZoomVideoSDKKey` and `ZoomVideoSDKSecret` using the `runtimeConfig` object. ## Step 4: Dynamic route for video chat We'll create a new file as `pages/call/[slug].vue` that will create a dynamic route for `/call/`. We can use this to create a link for each session based on user input. Users on the same link will be able to join the same session. In the setup script, we can use the `useRoute` composable to access the current route and the `useFetch` composable to fetch the JWT from the `/api/token` endpoint. ```html ``` We can then use the `JWT` and the `slug` in the template to render the `Videocall` component. Since the Zoom Video SDK is a client-side SDK and needs access to browser APIs, we'll wrap the `Videocall` component in a `ClientOnly` component to ensure that the component is only rendered on the client-side. ```html ... ``` ## Step 5: Build the videocall component Now for the fun part of building the video call component. We'll create a new file as `components/Videocall.vue` that will render the video call UI. #### Setup We'll import the Zoom Video SDK and define the props for the component, including the `slug` and `JWT` for authentication. We'll create a username for the user and we'll create a zoom video client with the `ZoomVideo.createClient()` method. ```html ``` #### Template for the videocall We're omitting the styling to make the code more readable, you can check out the styling on [GitHub](https://github.com/zoom/VideoSDK-VueNuxt-Quickstart/blob/cae938771f46d8bb6aed4a512db0362d7a14f4fa/components/Videocall.vue#L80). We render the video container with the `video-player-container` tag attaching the `videoContainer` ref to it. We wrap it in a `div` with `v-show` to only display it when the video session is active. ```html ... ``` We'll render the start call button with the `startCall` function only when the video session is not active using the `v-if` directive and the `inSession` ref. When the session is active, we'll render buttons to mute/unmute the camera/microphone and leave the call. We'll only render the buttons when the video session is active. We'll use the `videoMuted` and `audioMuted` refs to render the button text based on the current state of the camera/microphone. ```html ... ``` That's all the code we need to build a video conferencing app using the Zoom Video SDK. You can start a web server and run the app locally by executing `npm run dev` in the terminal. The app will be available at `http://localhost:3000/`, you can navigate to `/call/` to join a video call. ## Conclusion We hope this quick guide has given you a good starting point to build your own video conferencing app using the Zoom Video SDK with Vue and Nuxt. We've covered the basics of setting up the project, configuring the app, and building the video conferencing features, you can visit our documentation for adding more features like screen sharing, chat, and recording. You can also read our blog for the same project built with React and Next.js [here](/blog/nextjs-video-conferencing-app-using-the-zoom-video-sdk/). We'll be posting more guides for creating video chat apps with the Zoom Video SDK for different web technologies in the future. Stay tuned for more updates on our blog! --- _For further community discussion and insight from Zoom Developer Advocates and other developers, please check out the [Zoom Developer Forum](https://devforum.zoom.us/). For prioritized assistance and troubleshooting, take advantage of [Premier Developer Support](https://explore.zoom.us/en/support-plans/developer/) and [submit a ticket](https://support.zoom.com/hc/en/new-request?id=new_request&sys_id=7a69170f87cee15089a37408dabb3591)._