Integrate a Form Into External Website

If you have a website where you'd like to embed a Solidarity Tech form, the current method for accomplishing this is with an iframe. We will have a native embed widget released soon.

iframe method

To embed your page, create an iframe with the URL source pointing to your-site-url.solidarity.tech/page-url/embed. The embed path at the end of the page URL is critical to avoid any submission issues.

If you want the embedded iframe to break out of the iframe after the form is submitted, add the URL parameter ?breakout=true to the iframe src URL. With this setting, the entire page will be redirected after a form submission, not just the iframe content.


Troubleshooting Embedded Forms

"Refused to connect" error when clicking event/links in iframe

If you're embedding an events calendar or a page with clickable elements, users may see "refused to connect" when clicking on events or links within the iframe.

Solutions:

  1. Disable navigation in the embedded page - Go to Page Settings → enable "Hide Navbar" to prevent navigation conflicts
  2. Use ?breakout=true - Add this to your iframe URL so clicks redirect the full page instead of just the iframe
  3. Create a simpler embedded page - Consider creating a dedicated page specifically for embedding that removes elements that would navigate away

Form doesn't submit or shows errors

  1. Make sure your iframe URL ends with /embed (e.g., yoursite.solidarity.tech/join/embed)
  2. Check that your external site allows third-party cookies (some browsers block them by default)

Auto-Resizing iFrame Solution

To make your embedded form automatically resize its height to fit the content, you'll need to add JavaScript code to both the Solidarity Tech page and the external website.

Add to Your Solidarity Tech Page

Copy and paste the code below to the Solidarity Tech page under Page Settings -> Head HTML.

<script>
  window.addEventListener('load', function() {
    let lastHeight = 0;
    let lastWindowWidth = window.innerWidth;
    let isProcessing = false;
    let resizeTimeout;
    
    const sendHeight = function(reason) {
      if (isProcessing) {
        return;
      }
      
      const height = document.body.scrollHeight;
      
      // Only send if height changed by more than 5px
      if (Math.abs(height - lastHeight) > 5) {
        lastHeight = height;
        isProcessing = true;
        
        window.parent.postMessage({
          type: 'solidarity-tech-resize',
          height: height
        }, '*');
        
        // Reset processing flag
        setTimeout(function() {
          isProcessing = false;
        }, 500);
      } 
    };

    // Send initial height
    setTimeout(function() {
      sendHeight('initial load');
    }, 100);
    
    // SMART window resize - only on width changes
    window.addEventListener('resize', function() {
      const currentWidth = window.innerWidth;
      
      if (Math.abs(currentWidth - lastWindowWidth) > 10) {
        lastWindowWidth = currentWidth;
        
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(function() {
          sendHeight('browser resize');
        }, 300);
      }
    });
    
    // Handle form submissions and validation
    document.addEventListener('submit', function() {
      setTimeout(function() {
        sendHeight('form submit');
      }, 500);
    });
    
    // CRITICAL: Watch for validation errors appearing/disappearing
    const observer = new MutationObserver(function(mutations) {
      let shouldCheck = false;
      
      mutations.forEach(function(mutation) {
        // Check if error messages were added/removed or visibility changed
        if (mutation.type === 'childList') {
          mutation.addedNodes.forEach(function(node) {
            if (node.nodeType === 1 && (
              node.classList.contains('error') || 
              node.classList.contains('invalid') ||
              node.classList.contains('help-block') ||
              node.textContent.includes('Please') ||
              node.textContent.includes('invalid') ||
              node.textContent.includes('required')
            )) {
              shouldCheck = true;
            }
          });
        }
        
        // Check for style/class changes that might show/hide errors
        if (mutation.type === 'attributes' && 
            (mutation.attributeName === 'class' || mutation.attributeName === 'style')) {
          const target = mutation.target;
          if (target.classList.contains('error') || 
              target.classList.contains('invalid') ||
              target.classList.contains('help-block')) {
            shouldCheck = true;
          }
        }
      });
      
      if (shouldCheck) {
        console.log('🔍 VALIDATION CHANGE DETECTED');
        setTimeout(function() {
          sendHeight('validation change');
        }, 100);
      }
    });
    
    // Watch the entire form for validation changes
    const forms = document.querySelectorAll('form');
    forms.forEach(function(form) {
      observer.observe(form, {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['class', 'style']
      });
    });
    
    // Also watch for input events that might trigger validation
    document.addEventListener('input', function(e) {
      // Debounce input validation checks
      clearTimeout(window.inputTimeout);
      window.inputTimeout = setTimeout(function() {
        sendHeight('input validation');
      }, 200);
    });
    
  });
</script>

Add to the External Website

<script>
  // Add this code to the page where the iframe is embedded
  window.addEventListener('message', function(event) {
    // Check if message is from our iframe resize functionality
    if (event.data && event.data.type === 'solidarity-tech-resize') {
      // Find the iframe on this specific page
      // You may need to adjust the selector to target your specific iframe
      const iframe = document.querySelector('iframe');
      if (iframe) {
        // Set the height with a small buffer
        iframe.style.height = (event.data.height + 20) + 'px';
      }
    }
  });
</script>

Integration Instructions for Website Owners

Add the JavaScript code above directly to the page where you're embedding the iframe.

Platform-Specific Instructions:

WordPress: Add via a custom HTML block or page-specific custom code.
Squarespace: Add in Page Settings → Advanced → Page Header Code Injection.
Wix: Add via the Wix Editor using a custom code element on that specific page.
Other Platforms: Add to the specific page where the iframe is embedded.

This solution ensures the iframe will automatically adjust its height whenever the form content changes, eliminating scrollbars and providing a seamless user experience.