# Quickstart (/en/realtime-media/voice/quickstart/web)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

This Web quickstart shows you how to create a basic Voice Calling app using the Agora Voice SDK. Switch to the [Android](/en/realtime-media/voice/quickstart/android) or [iOS](/en/realtime-media/voice/quickstart/ios) quickstart, or choose another platform from the selector.

    * [RTC SDK API examples](https://github.com/AgoraIO/API-Examples-Web): Sample projects for the Agora RTC Web SDK 4.x, covering basic, advanced examples for Vue and React.

    ## Understand the tech [#understand-the-tech-3]

    To start a Voice Calling session, implement the following steps in your app:

    * **Initialize the Agora Engine**: Before calling other APIs, create and initialize an Agora Engine instance.

    * **Join a channel**: Call methods to create and join a channel.

    * **Send and receive audio**: All users can publish streams to the channel and subscribe to audio streams published by other users in the channel.

    ![Video calling workflow](https://assets-docs.agora.io/images/voice-sdk/get-started-sdk-voice.svg)

    ## Prerequisites [#prerequisites-3]

    * A [supported browser](reference/supported-platforms.md).
      Agora strongly recommends using the latest stable version of Google Chrome.

    * [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)

    * A microphone

    * A valid Agora account and project. Please refer to [Agora account management](manage-agora-account.md) for details.

    ## Set up your project [#set-up-your-project-3]

    This section shows you how to set up your Web project and install the Agora Voice SDK.

    <Tabs>
      <TabsList>
        <TabsTrigger value="new-project">
          Create a new project
        </TabsTrigger>

        <TabsTrigger value="existing-project">
          Add to an existing project
        </TabsTrigger>
      </TabsList>

      <TabsContent value="new-project">
        To initialize a new Vite project, take the following steps:

        1. Open a terminal and run the following command:

           ```bash
           npm create vite@latest agora_web_quickstart -- --template vanilla
           ```

           This creates a new folder named `agora_web_quickstart` and initializes a Vite project inside it using the `vanilla` JavaScript template.

        2. Navigate to the newly created folder. Download and set up dependencies for your project:

           ```bash
           cd agora_web_quickstart
           npm install
           ```

        3. Create a user interface for your project. The UI consists of buttons to join and leave a channel. Refer to [Create a user interface](#create-a-user-interface) to get a bare bones html layout.
      </TabsContent>

      <TabsContent value="existing-project">
        To add Voice Calling to your existing project, take the following steps:

        1. Create a JavaScript file in your project's `src` folder to add `AgoraRTCClient` code that implements specific application logic.

        2. Add an HTML file to your project to create a user interface. The UI consists of buttons to join and leave a channel. Refer to [Create a user interface](#create-a-user-interface) to get a bare bones HTML layout.

        3. Include the JavaScript file in your HTML file.

           ```html
           <script type="module" src="/src/main.js"></script>
           ```
      </TabsContent>
    </Tabs>

    ### Install the SDK [#install-the-sdk-3]

    Add the Voice SDK to your project:

    ```bash
    npm install agora-rtc-sdk-ng
    ```

    ## Implement Voice Calling [#implement-voice-calling-3]

    This section guides you through the implementation of basic real-time audio interaction in your app.

    The following figure illustrates the essential steps:

    <Accordions>
      <Accordion title="Quick start sequence">
        ![Quick start sequence](https://assets-docs.agora.io/images/video-sdk/quick-start-sequence-voice-web.svg)
      </Accordion>
    </Accordions>

    This guide includes [complete sample code](#complete-sample-code) that demonstrates implementing basic real-time interaction. To understand the core API calls in the sample code, review the following implementation steps.

    ### Import the `AgoraRTC` SDK [#import-the-agorartc-sdk]

    ```js
    import AgoraRTC from "agora-rtc-sdk-ng";
    ```

    ### Initialize an instance of `AgoraRTCClient` [#initialize-an-instance-of-agorartcclient]

    Call [`createClient`](https://api-ref.agora.io/en/video-sdk/web/4.x/interfaces/iagorartc.html#createclient) to initialize an `AgoraRTCClient` object. Set the [Channel mode](#channel-modes) based on your use case.

    For Voice Calling Set `mode` to `rtc`.

    ```javascript
    // RTC client instance
    let client = null;

    // Initialize the AgoraRTC client
    function initializeClient() {
      client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
      setupEventListeners();
    }
    ```

    ### Join a channel [#join-a-channel-3]

    To join a channel, call `join` with the following parameters:

    * **App ID**: The [App ID](manage-agora-account.md) for your project.

    * **Channel name**: The name of the channel to join. Clients that pass the same channel name join the same channel. If a channel with the specified name does not exist, it is created when the first user joins.

    * **Authentication token**: A dynamic key that authenticates a user when the client joins a channel. In a production environment, you obtain a token from a [token server](build/set-up-token-authentication/deploy-token-server.mdx) in your security infrastructure. For the purpose of this guide [Generate a temporary token](manage-agora-account.md).

    * **User ID**: A 32-bit signed integer that identifies a user in the channel. You can specify a unique user ID for each user yourself. If you set the user ID to `0` when joining a channel, the SDK generates a random number for the user ID.

    ```javascript
    // Join the channel and publish local audio
    async function joinChannel() {
      await client.join(appId, channel, token, uid);
      await createMicrophoneAudioTrack();
      await publishMicrophoneAudioTrack();
    }
    ```

    ### Create a local audio track [#create-a-local-audio-track]

    Use `createMicrophoneAudioTrack` to create a local audio track.

    ```javascript
    let localAudioTrack;
    async function createMicrophoneAudioTrack() {
      // Create a local audio track
      localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
    }
    ```

    ### Publish local media tracks [#publish-local-media-tracks]

    To make the created audio tracks available for other users in the channel, use the `publish` method.

    ```javascript
    async function publishMicrophoneAudioTrack() {
      await client.publish([localAudioTrack]);
    }
    ```

    See [Local audio tracks](#local-audio-tracks) to learn more about local tracks.

    ### Set up event listeners [#set-up-event-listeners]

    Use the `on` method to register event listeners for SDK events. The SDK triggers the `user-published` event when a user publishes an audio track in the channel. Similarly, it triggers the `user-unpublished` event when a user leaves the channel, goes offline, or unpublishes a media track.

    ```javascript
    // Handle client events
    function setupEventListeners() {
      // Set up event listeners for remote tracks
      client.on("user-published", async (user, mediaType) => {
        // Subscribe to the remote user when the SDK triggers the "user-published" event
        await client.subscribe(user, mediaType);

        // If the remote user publishes an audio track
        if (mediaType === "audio") {
          // Get the RemoteAudioTrack object in the AgoraRTCRemoteUser object
          const remoteAudioTrack = user.audioTrack;
          // Play the remote audio track
          remoteAudioTrack.play();
        }
      });

      // Handle the "user-unpublished" event to unsubscribe from the user's media tracks
      client.on("user-unpublished", async (user) => {
        // Remote user unpublished
      });
    }
    ```

    <CalloutContainer type="info">
      <CalloutDescription>
        To ensure that you receive all Voice SDK events, set up event listeners before joining a channel.
      </CalloutDescription>
    </CalloutContainer>

    For more information about other `AgoraRTCClient` events, refer to the [API reference](https://api-ref.agora.io/en/video-sdk/web/4.x/interfaces/iagorartcclient.html#event_channel_media_relay_event).

    ### Leave the channel [#leave-the-channel]

    To exit the channel, close the local audio track and call the `leave` method.

    ```javascript
    // Leave the channel and clean up
    async function leaveChannel() {
      // Stop the local audio track and release the microphone
      if (localAudioTrack) {
        localAudioTrack.close(); // Stop local audio
        localAudioTrack = null; // Clean up the track reference
      }
      // Leave the channel
      await client.leave();
    }
    ```

    ### Complete sample code [#complete-sample-code-3]

    A complete code sample demonstrating the basic process of real-time interaction is provided here for your reference. To use the sample, copy the following code to the JavaScript file in the project's `src` folder.

    <Accordions>
      <Accordion title="Complete sample code for real-time Voice Calling">
        ```js
        import AgoraRTC from "agora-rtc-sdk-ng";

        // RTC client instance
        let client = null;
        // Local audio track
        let localAudioTrack = null;

        // Connection parameters
        let appId = "<-- Insert app ID -->";
        let channel = "<-- Insert channel name -->";
        let token = "<-- Insert token -->";
        let uid = 0; // User ID

        // Initialize the AgoraRTC client
        function initializeClient() {
          client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
          setupEventListeners();
        }

        // Handle client events
        function setupEventListeners() {
          // Set up event listeners for remote tracks
          client.on("user-published", async (user, mediaType) => {
            // Subscribe to the remote user when the SDK triggers the "user-published" event
            await client.subscribe(user, mediaType);
            console.log("subscribe success");
            // If the remote user publishes an audio track.
            if (mediaType === "audio") {
              // Get the RemoteAudioTrack object in the AgoraRTCRemoteUser object.
              const remoteAudioTrack = user.audioTrack;
              // Play the remote audio track.
              remoteAudioTrack.play();
            }
          });

          // Listen for the "user-unpublished" event
          client.on("user-unpublished", async (user) => {
            // Remote user unpublished
          });
        }

        // Create a local audio track
        async function createLocalAudioTrack() {
          localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
        }

        // Join the channel and publish local audio
        async function joinChannel() {
          await client.join(appId, channel, token, uid);
          await createLocalAudioTrack();
          await publishLocalAudio();
          console.log("Publish success!");
        }

        // Publish local audio track
        async function publishLocalAudio() {
          await client.publish([localAudioTrack]);
        }

        // Leave the channel and clean up
        async function leaveChannel() {
          localAudioTrack.close(); // Stop local audio
          await client.leave();  // Leave the channel
          console.log("Left the channel.");
        }

        // Set up button click handlers
        function setupButtonHandlers() {
          document.getElementById("join").onclick = joinChannel;
          document.getElementById("leave").onclick = leaveChannel;
        }

        // Start the basic call process
        function startBasicCall() {
          initializeClient();
          window.onload = setupButtonHandlers;
        }

        startBasicCall();
        ```
      </Accordion>
    </Accordions>

    ### Create a user interface [#create-a-user-interface-3]

    Open `index.html` in the project's root folder and replace the contents with the following code to implement a basic client user interface:

    **Sample code to create the user interface**

    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Agora Web SDK Quickstart</title>
    </head>
    <body>
      <h2 class="left-align">Agora Web SDK Quickstart</h2>
        <div class="row">
          <div>
            <button type="button" id="join">Join</button>
            <button type="button" id="leave">Leave</button>
          </div>
        </div>
      <!-- Include the JavaScript file -->
      <script type="module" src="/src/main.js"></script>
    </body>
    </html>
    ```

    ## Test the sample code [#test-the-sample-code-3]

    Take the following steps to run and test the sample code:

    1. In your `.js` file, update the values for `appId`, and `token` with values from Agora Console. Use the same `channel` name you used to generate the token.

    2. To start the development server, use the following command:

       ```bash
       npm run dev
       ```

    3. Open your browser and navigate to the URL displayed in your terminal, for example, `http://localhost:5173`.

       You see the following page:

       ![image](https://assets-docs.agora.io/images/video-sdk/quickstart-ui-web.png)

    4. On a second device, repeat the previous steps to install and launch the app. Alternatively, use the [Web demo](https://webdemo.agora.io/basicVideoCall/index.html) or clone the [sample project on Github](https://github.com/AgoraIO/API-Examples-Web) to join the same channel and test the following use-cases:

       1. Click **Join** to join the channel.
       2. Enter the same app ID, channel name, and temporary token.

       Once your friend joins the channel, you can hear each other.

    <CalloutContainer type="info">
      <CalloutDescription>
        * Run the web app on a local server (localhost) for testing purposes only. When deploying to a production environment, use the HTTPS protocol.
        * Due to browser security policies that restrict HTTP addresses to 127.0.0.1, the Agora Web SDK only supports HTTPS protocol and `http://localhost` (`http://127.0.0.1`). Please do not use the HTTP protocol to access your project, except for `http://localhost` (`http://127.0.0.1`).
      </CalloutDescription>
    </CalloutContainer>

    ## Reference [#reference-3]

    This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.

    * If a firewall is deployed in your network environment, refer to [Connect with Cloud Proxy](build/manage-connection-and-quality/cloud-proxy.mdx) to use Agora services normally.

    ### Next steps [#next-steps-3]

    After implementing the quickstart sample, read the following documents to learn more:

    * To ensure communication security in a test or production environment, best practice is to obtain and use a token from an authentication server. For details, see [Secure authentication with tokens](build/set-up-token-authentication/use-tokens.mdx).

    ### Sample project [#sample-project-3]

    Agora provides open source sample projects on [GitHub](https://github.com/AgoraIO/API-Examples-Web) for your reference. Download or view the [basicVoiceCall](https://github.com/AgoraIO/API-Examples-Web/tree/main/src/example/basic/basicVoiceCall) project for a more detailed example.

    ### API reference [#api-reference-3]

    * [`AgoraRTC.createClient`](https://api-ref.agora.io/en/voice-sdk/web/4.x/interfaces/iagorartc.html#createclient)
    * [`IAgoraRTCRemoteUser`](https://api-ref.agora.io/en/voice-sdk/web/4.x/interfaces/iagorartcremoteuser.html)
    * [`play`](https://api-ref.agora.io/en/voice-sdk/web/4.x/interfaces/iremoteaudiotrack.html#play)
    * [`join`](https://api-ref.agora.io/en/voice-sdk/web/4.x/interfaces/iagorartcclient.html#join)
    * [`createMicrophoneAudioTrack`](https://api-ref.agora.io/en/voice-sdk/web/4.x/interfaces/iagorartc.html#createmicrophoneaudiotrack)
    * [`publish`](https://api-ref.agora.io/en/voice-sdk/web/4.x/interfaces/iagorartcclient.html#publish)
    * [AgoraRTCClient events](https://api-ref.agora.io/en/voice-sdk/web/4.x/interfaces/iagorartcclient.html#event_channel_media_relay_event)

    ### Channel modes [#channel-modes]

    The Voice SDK supports the following channel modes:

    * `rtc`: Communication use-case
    * `live`: Live broadcast use-case

    #### Communication use-case [#communication-use-case]

    It is suitable for use-cases where all users in the channel need to communicate with each other and the total number of users is not too large, such as multi-person conferences and online chats.

    #### Live broadcast use-case [#live-broadcast-use-case]

    It is suitable for use-cases where there are few publishers but many subscribers. In this use-case, the SDK defines two user roles: audience (default) and host. Hosts can send and receive audio, but audience cannot send and may only receive audio. You can specify user roles by setting the parameters `createClient` of role, or you can call `setClientRole` to dynamically modify user roles.

    ### Local audio tracks [#local-audio-tracks]

    The SDK uses a hierarchy where all local track objects derive from the `LocalTrack` base class. This class defines the common behavior for all local tracks. Specific track types, such as `LocalAudioTrack` inherit from `LocalTrack` and extend its functionality.

    To publish a local track, you call the `publish` method of the client with the `LocalTrack` object as an input parameter. This approach makes publishing a track independent of how you create your local track.

    Each type of `LocalTrack` comes with its own set of tools. For example, `LocalAudioTrack` lets you control the volume.

    The SDK includes more specific classes based on `LocalAudioTrack`. For example, the `MicrophoneAudioTrack`, is a type of `LocalAudioTrack` that you can use to publish audio from your microphone. It comes with extra features for controlling the microphone and adjusting audio quality.

    ### Other integration methods [#other-integration-methods]

    When you use `npm` to install the Web SDK, you can enable tree shaking to reduce the size of the app after integration. For details, see [Using tree shaking](build/optimize-and-operate/app-size-optimization.mdx).

    In addition to using `npm` to install the Web SDK, you can also use the following methods:

    * In the project HTML file, add the following tag to obtain the SDK from CDN:

      ```html
      <script src="https://download.agora.io/sdk/release/AgoraRTC_N-4.24.5.js"></script>
      ```

    * Download the Voice SDK package locally, save the `.js` files in the SDK package to the project directory, and then add the following tag to the project HTML file:

      ```html
      <script src="./AgoraRTC_N-4.24.5.js"></script>
      ```

    Visit the [Download](/en/api-reference/sdks?product=voice\&platform=web) page to obtain the link for the latest SDK version.

    ### Frequently asked questions [#frequently-asked-questions-2]

    **Why do I get a `digital envelope routines::unsupported` error when running the quickstart project locally?**

    This issue arises in projects configured with `webpack` for local execution due to changes in Node.js 16 and above. The modifications in Node.js, particularly its dependency on OpenSSL (detailed in the [node issue](https://github.com/nodejs/node/issues/29817)), impact the local development environment dependencies of the project. Refer to the [webpack issue](https://github.com/webpack/webpack/issues/14532) for details.

    Use one of the following solutions to resolve the issue:

    * Run the following command to set a temporary environment variable (Recommended):

      ```bash
      export NODE_OPTIONS=--openssl-legacy-provider
      ```

    * Temporarily switch to a lower version of Node.js.

    ### See also [#see-also-3]

    * [Error codes](reference/error-codes.mdx)

    * [Connection status management](build/manage-connection-and-quality/connection-status-management.mdx)

    
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
