` element. This is a web-component that renders the video elements, we'll bind the `ref` to the `videoContainerRef` element to access it in the component. We'll also display a button to start/join the session based on the `inSession` state.
```js
const Videocall = (props: { slug: string; JWT: string }) => {
...
return (
Session: {session}
{!inSession() ? (
) : (
...
```
Once we're in the session, we'll display the `CameraButton` and `MicButton` components to enable/disable the camera and microphone, we'll define these next. We'll also display a button to leave the session.
```js
...
)}
);
};
export default Videocall;
```
## Step 6: Adding mute buttons
The `MicButton` component will render the microphone button and handle the mute/unmute logic using the `muteAudio` and `unmuteAudio` methods on the `mediaStream` based on the `isAudioMuted` state.
```js
import type { VideoClient } from "@zoom/videosdk";
import { Mic, MicOff, Video, VideoOff } from "lucide-solid";
import { Accessor, Setter, Show } from "solid-js";
const MicButton = (props: {
client: typeof VideoClient;
isAudioMuted: Accessor;
setIsAudioMuted: Setter;
}) => {
const { client, isAudioMuted, setIsAudioMuted } = props;
const onMicrophoneClick = async () => {
const mediaStream = client.getMediaStream();
isAudioMuted() ? await mediaStream?.unmuteAudio() : await mediaStream?.muteAudio();
setIsAudioMuted(client.getCurrentUserInfo().muted ?? true);
};
return (
);
};
```
The `CameraButton` component will render the camera button and handle the mute/unmute logic using the `startVideo` and `stopVideo` methods on the `mediaStream` based on the `isVideoMuted` state. We call the renderVideo function to update the videos in the DOM.
```js
const CameraButton = (props: {
client: typeof VideoClient;
isVideoMuted: Accessor;
setIsVideoMuted: Setter;
renderVideo: (event: { action: "Start" | "Stop"; userId: number }) => Promise;
}) => {
const { client, isVideoMuted, setIsVideoMuted, renderVideo } = props;
const onCameraClick = async () => {
const mediaStream = client.getMediaStream();
if (isVideoMuted()) {
await mediaStream.startVideo();
setIsVideoMuted(false);
await renderVideo({ action: "Start", userId: client.getCurrentUserInfo().userId });
} else {
await mediaStream.stopVideo();
setIsVideoMuted(true);
await renderVideo({ action: "Stop", userId: client.getCurrentUserInfo().userId });
}
};
return (
);
};
```
That's all the code we need to build a video conferencing app using the Zoom Video SDK. You can launch the Solid.js app by running `npm run dev` in the root directory. The app will be available at `http://localhost:3000/`.

## 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 Solid & SolidStart. We've covered the basics of setting up the project, configuring the app, and building the video conferencing features. You can visit our [docs](/docs/video-sdk/web/) to learn more about the Zoom Video SDK and add other features to you app like screen sharing, virtual background, background noise suppression, and more.
You can also read our blog for the same project built with [React & Next.js](/blog/nextjs-video-conferencing-app-using-the-zoom-video-sdk/), [Vue & Nuxt](/blog/vue-nuxt-video-conferencing-app-using-the-zoom-video-sdk/) and [SvelteKit](/blog/sveltekit-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)._