> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/ui-customization/web-component-vs-iframe.md).

# Run WebViewer as a Web Component

Learn about the differences between using WebViewer as an iframe and a Web Component in version 11. Discover how to access the WebViewer DOM and apply CSS styles effectively. Upgrade your web experien

Starting in version 11 WebViewer will be instantiated in a Web Component by default instead of an iframe.

## What's New

There are some differences between working with WebViewer as an iframe and as a Web Component. Here are some of the key changes:

### Accessing the WebViewer DOM

When using an iframe, it is possible to access DOM elements using `instance.UI.iframeWindow.document`.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
instance.UI.iframeWindow.document.querySelector('.ModularHeader');
```

{% endcode %}
{% endtab %}
{% endtabs %}

However, with a Web Component, WebViewer is part of the main document but encapsulated within a Shadow DOM. Shadow DOM provides a contained scope for the Web Component, helping prevent unintended styling or script interference from the rest of the page. To access elements inside this Web Component, you need to first access its `shadowRoot` and then query within it.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
// there could be multiple instances of WebViewer on the page so the [0] is getting the first one
document.getElementsByTagName('apryse-webviewer')[0].shadowRoot.querySelector('.ModularHeader');
```

{% endcode %}
{% endtab %}
{% endtabs %}

This `shadowRoot` approach gives access to elements within the isolated part of the DOM where WebViewer resides. It respects the Shadow DOM’s encapsulation, which is key to keeping the component’s styles and scripts scoped and self-contained, while still allowing controlled access for customization or interaction when needed.

### Applying CSS Styles

Since WebViewer is encapsulated within a Shadow DOM, in order to apply CSS styles to elements in WebViewer you need to use the `:host` selector when using the `css` option in your WebViewer constructor. This selector targets the Web Component itself, allowing you to style its elements from the outside.

The following code would style the WebViewer to use white icons and blue headers.

{% tabs %}
{% tab title="CSS" %}
{% code lineNumbers="true" %}

```css
:host {
    --icon-color: #FFFFFF !important;

    .ModularHeader {
      background-color: #00a5e4;
    }
  }
```

{% endcode %}
{% endtab %}
{% endtabs %}

You can then include the CSS file in the `css` property of your WebViewer constructor like so:

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
Webviewer(
    {
      path: '/path/to/your/webviewer',
      initialDoc: '/path/to/your/document.pdf',
      css: '/path/to/your/styles.css'
    },
    viewerElement
  ).then((instance) => {

  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

Without using the `:host` selector, the styles would not be applied to the WebViewer.

## iframe vs Web Component

Up until now, WebViewer has been instantiated using an iframe. An iframe, or inline frame, is an HTML document embedded inside another HTML document. Iframes have several benefits, such as content isolation and the ability to display content from different sources. However, they also present certain drawbacks. For instance, iframes can slow down site performance as the browser needs to load two separate pages. They can also pose accessibility challenges for assistive technologies like screen readers. Furthermore, running WebViewer in an iframe prevents the parent page from accessing its content directly, limiting opportunities for data gathering and analytics to better understand how users interact with your documents.

### Web Component: The Reusable Powerhouses

Web Components are a suite of web platform APIs that allow developers to create custom, reusable, encapsulated HTML tags for use in web pages and apps. As part of the web browser standard, they're an excellent choice for creating reusable code modules.

Benefits of Web Components:

* Encapsulation: Styles and behaviors within a web component are self-contained, preventing conflict with other code by avoiding global scope leakage.
* Reusability: Web Components can be reused across different projects or even within different parts of the same project, enhancing development efficiency.
* Interoperability: Web Components integrate well with existing web technologies and are compatible with any JavaScript library or framework that supports HTML.
* Standardization: Built on web standards, modern browsers natively support Web Components without the need for additional libraries.

### WebViewer as a Web Component

With the release of version 11, WebViewer is now instantiated as a Web Component by default. This allows you to leverage the advantages of encapsulation and reusability while giving your site direct access to the viewer's content. As a result, you can create a more seamless experience for your users and gather data and analytics on how they interact with your documents.

Previously when using NPM to integrate WebViewer into your project, there needed to be minimal code changes to instantiate WebViewer as a Web Component.

In version 11, there is no longer any need to use `WebViewer.WebComponent` as Web Component is now the default for WebViewer. The following code snippet demonstrates how to instantiate WebViewer as a Web Component:

<pre class="language-js" data-line-numbers><code class="lang-js">import WebViewer from '@pdftron/webviewer'

WebViewer({
  path: '/public/webviewer',
  licenseKey: '<code class="expression">visitor.claims.wvKey || "YOUR_LICENSE_KEY"</code>',
}, document.getElementById('viewer'))
  .then(instance => {
    const { UI, Core } = instance;
    const { documentViewer, annotationManager, Tools, Annotations } = Core;
    // call methods from UI, Core, documentViewer and annotationManager as needed

    documentViewer.addEventListener('documentLoaded', () => {
      // call methods relating to the loaded document
    });

    instance.UI.loadDocument('https://pdftron.s3.amazonaws.com/downloads/pl/demo-annotated.pdf');
  })
</code></pre>

[DocumentViewer#documentLoaded](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:documentLoaded) [DocumentViewer.loadDocument](https://sdk.apryse.com/api/web/UI.html#.loadDocument)

### Using an iframe

If you prefer to use an iframe, you can still do so by replacing the `WebViewer` function with `WebViewer.Iframe` and it will work as it did before.

<pre class="language-js" data-line-numbers><code class="lang-js">import WebViewer from '@pdftron/webviewer'
WebViewer.Iframe({
  path: '/public/webviewer',
  licenseKey: '<code class="expression">visitor.claims.wvKey || "YOUR_LICENSE_KEY"</code>',
}, document.getElementById('viewer'))
  .then(instance => {
    const { UI, Core } = instance;
    const { documentViewer, annotationManager, Tools, Annotations } = Core;
    // call methods from UI, Core, documentViewer and annotationManager as needed

    documentViewer.addEventListener('documentLoaded', () => {
      // call methods relating to the loaded document
    });

    instance.UI.loadDocument('https://pdftron.s3.amazonaws.com/downloads/pl/demo-annotated.pdf');
  })
</code></pre>

Manual integration is also straightforward. For more info please refer to the [manual integration guide.](/web/get-started/manually.md)

## Remote worker files in WebViewer Web Component

Large resource and worker files can be hosted on a CDN or some other external server for faster access and caching. WebViewer provides several APIs for dealing with cross-origin resource sharing issues and you can read more about it in this [Cross Origin Workers](/web/advanced/cross-origin-workers.md#cross-origin-workers-in-webviewer-webcomponent) guide.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/ui-customization/web-component-vs-iframe.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
