> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myperch.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Implementation Guide

> Step-by-step instructions for implementing Perch embeddable tools across different platforms and frameworks

This guide walks through the process of implementing Perch embeddable tools on various Content Management Systems (CMS) and technical platforms.

## Basic embed code structure

All Perch widgets use the same simple two-line integration. The widget ID will either be provided by your Perch representative (for custom configurations) or you can use one of the predefined static widget IDs for Lead Management:

```html theme={null}
<!-- DIV PORTION -->
<div class="perch-widget" widget-id="your-widget-id">
    <div class="perch-widget-loading-indicator">Loading...</div>
</div>

<!-- SCRIPT PORTION -->
<script src="https://embeds.myperch.io/assets/perch-embed-widget.js"></script>
```

**Widget ID Options:**

* **Custom widgets**: Your Perch representative provides a specific widget ID (e.g., `ABC123`)
* **Static Lead Management widgets**: Use predefined IDs following `static-{portal}-{parent}` format (see [Widget Embedding](/embeds/lead-management#widget-embedding) for all available IDs)

<Info>
  The Perch widget script is only 1KB in size, ensuring minimal impact on your page load performance.
</Info>

### Custom loading indicator

To improve the client user experience, we've added a feature to provide a custom loading indicator. You can use the inner `<div>` with the class `.perch-widget-loading-indicator` to insert a plain text loader (e.g. 'Loading...') that will be visible while the tool is being downloaded and rendered.

You can replace the contents of this `<div>` with a custom message or a loading indicator of your choice to better match your branding:

```html theme={null}
<div class="perch-widget" widget-id="YOUR-WIDGET-ID">
    <div class="perch-widget-loading-indicator">
        <span>Loading mortgage calculator...</span>
        <!-- Or add your own custom loading animation -->
    </div>
</div>
```

<Info>
  Be sure that you retain the `.perch-widget-loading-indicator` class as this is what our script looks for when removing the loading indicator upon successful initialization of your widget.
</Info>

***

## CMS-specific instructions

<Warning>
  **Important**: In most cases, the CMS editor will not execute JavaScript and therefore the tool will not render in the editor. Instead you will see the "Loading..." text. To view the rendered tool, select your CMS's "preview" option to see the live version.
</Warning>

### WordPress + Elementor

<Frame>
  <iframe src="https://play.vidyard.com/JfhPqPBfqaqxSYqaG3ARmE" width="100%" height="360" frameborder="0" allowtransparency="true" allowfullscreen />
</Frame>

1. Navigate to the page where you want to embed the tool within your editor
2. Add a new **HTML** element using Elementor
3. Paste the provided `<div>` and `<script>` tags into the HTML element
4. Save and publish your changes

### Webflow

1. Go to the page you wish to embed the tool on
2. Add an **Embed** element to your page
3. Paste the provided `<div>` and `<script>` tags into the Embed element
4. Publish your site to see the tool in action

### Squarespace

1. Go to the page where you want to embed the tool
2. Click on the **+** icon to add a new block and select **Code**
3. Paste the provided `<div>` and `<script>` tags into the Code block
4. Apply and save your changes

### KVCore

KVCore is different from other website CMS in that you need to enter the `<div>` and `<script>` tags in different locations:

1. **Add the script tag**:
   * Hover over **Web & IDX** in your sidebar navigation to reveal the menu
   * Select **Website Settings** to open your website's setting panel
   * Scroll down to the **custom header** section
   * Put your `<script>` tag in this box and hit **save**

2. **Add the div portion**:
   * Go into your custom page editor
   * Click the embed option **`<>`**
   * Paste the `<div>` portion of your tool into the box
   * Hit save and apply your changes to the site

## Single Page Application integration

Perch Widgets can be easily integrated into single-page applications (SPAs) like Angular, Vue.js, or React. However, SPAs manage the DOM differently compared to traditional multi-page websites.

### Why manual initialization is needed

In a traditional setup, the widget script relies on the DOM ready event to initialize. But in SPAs, the DOM is often dynamically updated, and elements containing the widget may not be available at the traditional DOM ready event. To support dynamic rendering in SPAs, we've added a custom event emitter that allows you to manually trigger widget initialization whenever your components mount.

### Steps to initialize a widget in an SPA

1. **Load the Perch widget script** - Choose one of two approaches:
   * **Static approach**: Add the script tag to your main HTML file (e.g., `index.html`)
   * **Dynamic approach**: Load the script programmatically in your component code
2. **Insert the widget div into your HTML** where you want it to appear
3. **Listen for the appropriate lifecycle hook** in your framework that guarantees the element containing the widget is present in the DOM
4. **Emit the Perch widget initialization event** once the widget's DOM element is available

### Basic examples

<Tabs>
  <Tab title="Static Loading">
    Add the script tag to your main HTML file. This ensures the script is available immediately:

    ```html index.html theme={null}
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>Your App</title>
      <script src="https://embeds.myperch.io/assets/perch-embed-widget.js"></script>
    </head>
    <body>
      <div id="root"></div>
    </body>
    </html>
    ```

    Add the widget div where you want it to appear:

    ```html theme={null}
    <div class="perch-widget" widget-id="your-widget-id">
      <div class="perch-widget-loading-indicator">Loading...</div>
    </div>
    ```

    When using this approach, your initialization function only needs to emit the event:

    ```javascript theme={null}
    function initializePerchWidget(widgetId) {
      const event = new CustomEvent('perch-widget:init', {
        detail: {
          perchWidgetId: widgetId
        }
      });
      window.dispatchEvent(event);
    }

    // Call this after the widget div is added to the page
    initializePerchWidget('your-widget-id');
    ```
  </Tab>

  <Tab title="Dynamic Loading">
    Load the script programmatically in your component code. This is useful if you want to load the script only when needed.

    First, add the widget div where you want it to appear:

    ```html theme={null}
    <div class="perch-widget" widget-id="your-widget-id">
      <div class="perch-widget-loading-indicator">Loading...</div>
    </div>
    ```

    Then use this function to load the script and initialize the widget:

    ```javascript theme={null}
    function initializePerchWidget(widgetId) {
      // Helper function to emit the initialization event
      function emitInitEvent() {
        const event = new CustomEvent('perch-widget:init', {
          detail: {
            perchWidgetId: widgetId
          }
        });
        window.dispatchEvent(event);
      }
      
      // Check if script is already loaded
      const existingScript = document.querySelector('script[src*="perch-embed-widget.js"]');
      
      if (existingScript) {
        // Script already exists, just emit the initialization event
        emitInitEvent();
        return;
      }
      
      // Create and append the script tag
      const script = document.createElement('script');
      script.src = 'https://embeds.myperch.io/assets/perch-embed-widget.js';
      script.async = true;
      
      // Initialize widget once script loads
      script.onload = emitInitEvent;
      
      // Append script to document head
      document.head.appendChild(script);
    }

    // Call this after the widget div is added to the page
    initializePerchWidget('your-widget-id');
    ```
  </Tab>
</Tabs>

### Framework examples

The following examples demonstrate both approaches. Each example uses the dynamic loading approach, but you can simplify the code by using static loading instead (just add the script to your HTML and remove the script loading logic).

#### Angular example

```typescript widget-container.component.ts theme={null}
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-widget-container',
  template: `<div class="perch-widget" widget-id="abc123">
    <div class="perch-widget-loading-indicator">Loading...</div>
  </div>`,
})
export class WidgetContainerComponent implements OnInit {

  ngOnInit() {
    this.initializePerchWidget('abc123');
  }

  private initializePerchWidget(widgetId: string): void {
    // Helper function to emit the initialization event
    const emitInitEvent = () => {
      const event = new CustomEvent('perch-widget:init', {
        detail: {
          perchWidgetId: widgetId
        }
      });
      window.dispatchEvent(event);
    };
    
    // Check if script is already loaded
    const existingScript = document.querySelector('script[src*="perch-embed-widget.js"]');
    
    if (existingScript) {
      // Script already exists, just emit the initialization event
      emitInitEvent();
      return;
    }
    
    // Create and append the script tag
    const script = document.createElement('script');
    script.src = 'https://embeds.myperch.io/assets/perch-embed-widget.js';
    script.async = true;
    
    // Initialize widget once script loads
    script.onload = emitInitEvent;
    
    // Append script to document head
    document.head.appendChild(script);
  }
}
```

#### Vue.js example

```vue WidgetContainer.vue theme={null}
<template>
  <div class="perch-widget" widget-id="abc123">
    <div class="perch-widget-loading-indicator">Loading...</div>
  </div>
</template>

<script>
export default {
  mounted() {
    this.initializePerchWidget('abc123');
  },
  methods: {
    initializePerchWidget(widgetId) {
      // Helper function to emit the initialization event
      const emitInitEvent = () => {
        const event = new CustomEvent('perch-widget:init', {
          detail: {
            perchWidgetId: widgetId
          }
        });
        window.dispatchEvent(event);
      };
      
      // Check if script is already loaded
      const existingScript = document.querySelector('script[src*="perch-embed-widget.js"]');
      
      if (existingScript) {
        // Script already exists, just emit the initialization event
        emitInitEvent();
        return;
      }
      
      // Create and append the script tag
      const script = document.createElement('script');
      script.src = 'https://embeds.myperch.io/assets/perch-embed-widget.js';
      script.async = true;
      
      // Initialize widget once script loads
      script.onload = emitInitEvent;
      
      // Append script to document head
      document.head.appendChild(script);
    }
  }
}
</script>
```

#### React example

```javascript WidgetContainer.jsx theme={null}
import { useEffect } from 'react';

function WidgetContainer() {
  useEffect(() => {
    initializePerchWidget('abc123');
  }, []);

  const initializePerchWidget = (widgetId) => {
    // Helper function to emit the initialization event
    const emitInitEvent = () => {
      const event = new CustomEvent('perch-widget:init', {
        detail: {
          perchWidgetId: widgetId
        }
      });
      window.dispatchEvent(event);
    };
    
    // Check if script is already loaded
    const existingScript = document.querySelector('script[src*="perch-embed-widget.js"]');
    
    if (existingScript) {
      // Script already exists, just emit the initialization event
      emitInitEvent();
      return;
    }
    
    // Create and append the script tag
    const script = document.createElement('script');
    script.src = 'https://embeds.myperch.io/assets/perch-embed-widget.js';
    script.async = true;
    
    // Initialize widget once script loads
    script.onload = emitInitEvent;
    
    // Append script to document head
    document.head.appendChild(script);
  };

  return (
    <div className="perch-widget" widget-id="abc123">
      <div className="perch-widget-loading-indicator">Loading...</div>
    </div>
  );
}

export default WidgetContainer;
```

### Best practices for SPAs

* **Load the script only once** - The initialization function includes checks to prevent loading the script multiple times, which is important for performance and avoiding conflicts
* **Ensure that each widget is initialized only once per page**, particularly in SPAs where pages may not fully reload
* **Dispatch the event** at the earliest point where you can guarantee the DOM element for the widget is present
* **Clean up properly** when components are unmounted to prevent memory leaks

## Custom implementations

For custom implementations or unique technical requirements, refer to the [Basic examples](#basic-examples) section above for the complete initialization function. Choose either the static or dynamic loading approach based on your needs.

## Troubleshooting

### Widget not appearing

* Ensure the script tag is included on the page
* Check that the widget ID matches what was provided by Perch
* Verify JavaScript is enabled and not being blocked

### Widget shows "Loading..." indefinitely

* Check browser console for JavaScript errors
* Ensure the page is being viewed live (not in editor mode)
* Verify the script URL is accessible

### Multiple widgets on one page

* Each widget should have a unique widget-id
* The script only needs to be included once per page
* All widgets will initialize automatically
