# Creating Viewers

We will now use the data returned to us from our application server to create and start a WebViewer in our browser. You will notice that our current implementation of `createNewViewer` in index.html waits for a response from the server before simply echoing out the data it receives. We would like to now put that data to use. We will do that by performing the following steps:

1. Instantiate an HTML template to create required DOM elements for our viewer.
2. Create and start a Communicator.WebViewer object referencing a container we created in step 1.
3. Save the newly created WebViewer in a map so we can access it later.

Start by creating a Map to hold our WebViewers outside of the `createNewViewer` function:

    const viewerMap = new Map();

Next, replace the console log statement in `createNewViewer` with its actual implementation:

    let templateText = $("#viewer-template").html();
    $("#viewers").append(templateText.replace(/{{id}}/g, data.id));

    const rendererType = data.rendererType === "csr" ? Communicator.RendererType.Client : Communicator.RendererType.Server;

    const viewer = new Communicator.WebViewer({
      containerId: `viewer-${data.id}`,
      endpointUri: data.endpoint,
      model: "helloworld",
      rendererType: rendererType
    });

    viewer.start();

    viewerMap.set(data.id, viewer);

We first reference the template that is provided in the HTML and instantiate it by performing a string replace with the ID of our newly created viewer. We will be adding support for Server Side Rendering in a later section of the tutorial, so for now, `data.rendererType` will always have the value `csr`. Next, our Communicator.WebViewer is created and started. The endpoint is plugged in directly from the response of our application server. We are assured that when our request to spawn an instance returns, that the application is ready to connect and no race condition at connect time will occur. Finally, we save the WebViewer object in our Map, keyed on its Id. This will come in handy later in the tutorial when we add support for removing viewers.

Note

In a production environment, you generally do not want to have traffic to your ts3d_sc_server instances going over non-standard ports. This is due to many networks restricting traffic on such ports. It is recommended to use a reverse proxy to ensure that all traffic is going over standard, trusted ports. Please refer to the HOOPS Visualize Web documentation on this topic for additional information.

At this point, clicking the remove button will throw a JavaScript error since we have not implemented the `removeViewer` method yet. We will fix that in the next section.

Conversation saved
HOOPSY BETA

### Hello! I'm HOOPSY

Your Docs generative AI assistant. Ask me anything about HOOPS Visualize Web or choose a sample question below to start a conversation:

What is HOOPS Visualize Web?
What are the latest release notes for HOOPS Visualize Web?
How do I start evaluating HOOPS Visualize Web?
How do I write my first sample application?
How can I get assistance?

HOOPSY may store conversations according to OpenAI's policy. Responses may not always be accurate.

HOOPSY is thinking...