Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.tally.so/llms.txt

Use this file to discover all available pages before exploring further.

Loading the Tally widget script from a React component is a useEffect away. The snippet below mounts the script on first render, then calls Tally.loadEmbeds() once it’s available. If the script is already loaded on the page, it skips the script tag and just loads the embeds.
import { useEffect } from 'react';

const MyComponent = () => {
  // The code below will load the embed
  useEffect(() => {
    const widgetScriptSrc = 'https://tally.so/widgets/embed.js';

    const load = () => {
      // Load Tally embeds
      if (typeof Tally !== 'undefined') {
        Tally.loadEmbeds();
        return;
      }

      // Fallback if window.Tally is not available
      document.querySelectorAll('iframe[data-tally-src]:not([src])').forEach((iframeEl) => {
        iframeEl.src = iframeEl.dataset.tallySrc;
      });
    };

    // If Tally is already loaded, load the embeds
    if (typeof Tally !== 'undefined') {
      load();
      return;
    }

    // If the Tally widget script is not loaded yet, load it
    if (document.querySelector(`script[src="${widgetScriptSrc}"]`) === null) {
      const script = document.createElement('script');
      script.src = widgetScriptSrc;
      script.onload = load;
      script.onerror = load;
      document.body.appendChild(script);
      return;
    }
  }, []);

  return (
    <div>
      <iframe
        data-tally-src="https://tally.so/embed/mRoDv3?alignLeft=1&hideTitle=1&transparentBackground=1&dynamicHeight=1"
        loading="lazy"
        width="100%"
        height="216"
        frameBorder={0}
        marginHeight={0}
        marginWidth={0}
        title="Newsletter subscribers"></iframe>
    </div>
  );
};

export default MyComponent;
Prefer a package? The community-maintained react-tally wrapper by Nititech provides the same behavior as a drop-in component.