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

# Tag Integration Guide

> Merchant-specific integration instructions for implementing Mention Me JavaScript tags

export const MerchantContext = () => {
  const PARTNER_STORAGE_KEY = "mm-docs-partner";
  const escapeHtml = str => str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
  const getStoredPartner = () => {
    try {
      const raw = localStorage.getItem(PARTNER_STORAGE_KEY);
      if (!raw) return null;
      const data = JSON.parse(raw);
      if (data && data.partnerCode) return data;
    } catch (e) {}
    return null;
  };
  const setStoredPartner = data => {
    try {
      localStorage.setItem(PARTNER_STORAGE_KEY, JSON.stringify(data));
    } catch (e) {}
  };
  const clearStoredPartner = () => {
    try {
      localStorage.removeItem(PARTNER_STORAGE_KEY);
    } catch (e) {}
  };
  const captureQueryParams = () => {
    const params = new URLSearchParams(window.location.search);
    const partner = params.get("partner");
    const name = params.get("name");
    if (partner) {
      const data = {
        partnerCode: partner
      };
      if (name) data.displayName = name;
      setStoredPartner(data);
      params.delete("partner");
      params.delete("name");
      const qs = params.toString();
      const clean = window.location.pathname + (qs ? "?" + qs : "") + window.location.hash;
      window.history.replaceState(null, "", clean);
      return data;
    }
    return getStoredPartner();
  };
  const isLocal = typeof window !== "undefined" && window.location.hostname === "localhost";
  const API_BASE = isLocal ? "http://localhost:3001" : "https://app.mention-me.com";
  const SIGN_IN_BASE = isLocal ? "http://localhost:3001/sign-in" : "https://app.mention-me.com/sign-in";
  const MERCHANT_WINDOW_KEY = "__mmMerchantContext";
  const publishMerchant = data => {
    window[MERCHANT_WINDOW_KEY] = data;
    window.dispatchEvent(new CustomEvent("mm-merchant-ready", {
      detail: data
    }));
  };
  const clearMerchant = () => {
    delete window[MERCHANT_WINDOW_KEY];
  };
  const BADGE_ID = "mm-partner-badge";
  const showPartnerBadge = (partnerData, source) => {
    if (document.getElementById(BADGE_ID)) return;
    const nav = document.getElementById("navigation-items");
    if (!nav || !nav.parentNode) return;
    const badge = document.createElement("div");
    badge.id = BADGE_ID;
    badge.className = "mm-partner-badge";
    const hasName = partnerData.displayName && partnerData.displayName !== partnerData.partnerCode;
    const heading = hasName ? escapeHtml(partnerData.displayName) : escapeHtml(partnerData.partnerCode);
    const code = hasName ? escapeHtml(partnerData.partnerCode) : "";
    const codeStr = code ? ' <span class="mm-partner-badge-code">' + code + '</span>' : '';
    const resetTitle = source === "clerk" ? "Sign out and switch account" : "Clear personalisation";
    badge.innerHTML = '<div class="mm-partner-badge-inner">' + '<span class="mm-partner-badge-content">' + '<span class="mm-partner-badge-context">Personalised for </span>' + '<span class="mm-partner-badge-name">' + heading + '</span>' + codeStr + '</span>' + '<button class="mm-partner-badge-reset" title="' + resetTitle + '">&times;</button>' + '</div>';
    nav.parentNode.insertBefore(badge, nav);
    badge.querySelector(".mm-partner-badge-reset").addEventListener("click", e => {
      e.preventDefault();
      e.stopPropagation();
      if (source === "clerk" && window.Clerk && window.Clerk.signOut) {
        clearMerchant();
        const redirect = SIGN_IN_BASE + "?redirect_url=" + encodeURIComponent(window.location.href);
        window.Clerk.signOut().then(() => {
          window.location.href = redirect;
        }).catch(() => {
          window.location.reload();
        });
        return;
      }
      clearStoredPartner();
      window.location.reload();
    });
  };
  const removePartnerBadge = () => {
    const el = document.getElementById(BADGE_ID);
    if (el) el.remove();
  };
  const showNotices = () => {
    document.querySelectorAll("[data-mm-sign-in]").forEach(el => {
      el.style.display = "";
    });
    const redirect = SIGN_IN_BASE + "?redirect_url=" + encodeURIComponent(window.location.href);
    document.querySelectorAll("[data-mm-sign-in-link]").forEach(a => {
      a.href = redirect;
    });
  };
  const hideNotices = () => {
    document.querySelectorAll("[data-mm-sign-in]").forEach(el => {
      el.style.display = "none";
    });
  };
  const walkCodeBlocks = replacements => {
    document.querySelectorAll("pre code").forEach(codeEl => {
      let html = codeEl.innerHTML;
      if (replacements) {
        for (const [from, to] of replacements) {
          html = html.split(from).join(escapeHtml(to));
        }
      }
      const paramStyle = "color:inherit;filter:brightness(110%);font-weight:bold;text-decoration:underline;cursor:pointer";
      html = html.replace(/(\?|&amp;)([a-z_]+)=/g, (match, prefix, name) => {
        const slug = name.replace(/_/g, "-");
        const target = document.getElementById("param-" + slug);
        if (!target) return match;
        return prefix + '<a href="#param-' + slug + '" style="' + paramStyle + '">' + name + "</a>=";
      });
      codeEl.innerHTML = html;
    });
  };
  const observeTabSwitches = callback => {
    let processing = false;
    const observer = new MutationObserver(() => {
      if (processing) return;
      processing = true;
      setTimeout(() => {
        callback();
        processing = false;
      }, 50);
    });
    setTimeout(() => {
      const tabs = document.querySelector("[role='tablist']");
      if (tabs && tabs.parentElement) {
        observer.observe(tabs.parentElement, {
          attributes: true,
          subtree: true,
          childList: true
        });
      }
    }, 500);
  };
  const pollForClerk = (onReady, onTimeout) => {
    let n = 0;
    const tick = () => {
      if (window.Clerk && window.Clerk.loaded) {
        return onReady(window.Clerk);
      }
      if (++n < 40) {
        setTimeout(tick, 250);
      } else {
        onTimeout();
      }
    };
    setTimeout(tick, 100);
  };
  const fetchMerchantFromAPI = () => {
    return fetch(API_BASE + "/api/docs/context", {
      credentials: "include",
      cache: "no-store"
    }).then(res => res.ok ? res.json() : null);
  };
  useEffect(() => {
    let cancelled = false;
    const urlPartner = captureQueryParams();
    const onPersonalised = (merchant, source) => {
      if (cancelled) return;
      const replacements = [["YOUR_PARTNER_CODE", merchant.partnerCode]];
      if (merchant.displayName) {
        replacements.push(["YOUR_TRADING_NAME", merchant.displayName]);
      }
      hideNotices();
      showPartnerBadge(merchant, source);
      walkCodeBlocks(replacements);
      observeTabSwitches(() => walkCodeBlocks(replacements));
    };
    const onUnauth = () => {
      if (cancelled) return;
      clearMerchant();
      removePartnerBadge();
      showNotices();
      walkCodeBlocks(null);
      observeTabSwitches(() => walkCodeBlocks(null));
    };
    const tryUrlFallback = () => {
      if (cancelled) return;
      if (urlPartner) {
        onPersonalised(urlPartner, "url");
      } else {
        onUnauth();
      }
    };
    if (!document.cookie.includes("__client_uat")) {
      tryUrlFallback();
      return;
    }
    pollForClerk(clerk => {
      if (cancelled) return;
      if (!clerk.session) {
        tryUrlFallback();
        return;
      }
      fetchMerchantFromAPI().then(data => {
        if (data) {
          publishMerchant(data);
          onPersonalised(data, "clerk");
        } else {
          tryUrlFallback();
        }
      }).catch(() => tryUrlFallback());
    }, () => {
      if (!cancelled) tryUrlFallback();
    });
    return () => {
      cancelled = true;
    };
  }, []);
  return null;
};

<MerchantContext />

## Welcome

Welcome to our product integration instructions.

**Mention Me** seamlessly integrates into brands' websites to incentivise, track and reward referrals throughout the customer journey, as well as further enhance the customer experience to turn even more shoppers into brand advocates.

## Select your referral flow

<Tabs>
  <Tab title="Standard">
    <Frame>
      <img src="https://mintcdn.com/mentionme/Dcv4Ct-ZIyuK4Pcd/images/developer-docs/integration/flows/standard-v3.png?fit=max&auto=format&n=Dcv4Ct-ZIyuK4Pcd&q=85&s=a14de29d45ab338d45e3ac9f670c839c" alt="Standard referral journey" style={{backgroundColor: 'white', padding: '16px'}} width="2000" height="1146" data-path="images/developer-docs/integration/flows/standard-v3.png" />
    </Frame>
  </Tab>

  <Tab title="First Orders">
    <Tabs>
      <Tab title="Client fulfils">
        <Frame>
          <img src="https://mintcdn.com/mentionme/Dcv4Ct-ZIyuK4Pcd/images/developer-docs/integration/flows/first-orders-client-fulfils-v3.png?fit=max&auto=format&n=Dcv4Ct-ZIyuK4Pcd&q=85&s=31db3c22395e6c36ef657748c5f20cec" alt="First orders client fulfils" style={{backgroundColor: 'white', padding: '16px'}} width="2000" height="1146" data-path="images/developer-docs/integration/flows/first-orders-client-fulfils-v3.png" />
        </Frame>
      </Tab>

      <Tab title="Manual approve">
        <Frame>
          <img src="https://mintcdn.com/mentionme/Dcv4Ct-ZIyuK4Pcd/images/developer-docs/integration/flows/first-orders-manual-v3.png?fit=max&auto=format&n=Dcv4Ct-ZIyuK4Pcd&q=85&s=1a80428c0f80b966e18ec71f771406b6" alt="First orders manual approve" style={{backgroundColor: 'white', padding: '16px'}} width="2000" height="1150" data-path="images/developer-docs/integration/flows/first-orders-manual-v3.png" />
        </Frame>
      </Tab>

      <Tab title="3rd party vouchers">
        <Frame>
          <img src="https://mintcdn.com/mentionme/Dcv4Ct-ZIyuK4Pcd/images/developer-docs/integration/flows/first-orders-vouchers-v3.png?fit=max&auto=format&n=Dcv4Ct-ZIyuK4Pcd&q=85&s=c9d5a146a51f025a1fe51e1bcddb327c" alt="First orders third party vouchers" style={{backgroundColor: 'white', padding: '16px'}} width="2000" height="1146" data-path="images/developer-docs/integration/flows/first-orders-vouchers-v3.png" />
        </Frame>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="New Signups">
    <Tabs>
      <Tab title="Client fulfils">
        <Frame>
          <img src="https://mintcdn.com/mentionme/Dcv4Ct-ZIyuK4Pcd/images/developer-docs/integration/flows/new-signups-client-fulfils-v3.png?fit=max&auto=format&n=Dcv4Ct-ZIyuK4Pcd&q=85&s=5f70555cefb9e0d3ba1061b47ef9cad0" alt="New signups client fulfils" style={{backgroundColor: 'white', padding: '16px'}} width="2000" height="1146" data-path="images/developer-docs/integration/flows/new-signups-client-fulfils-v3.png" />
        </Frame>
      </Tab>

      <Tab title="Manual approve">
        <Frame>
          <img src="https://mintcdn.com/mentionme/Dcv4Ct-ZIyuK4Pcd/images/developer-docs/integration/flows/new-signups-manual-v3.png?fit=max&auto=format&n=Dcv4Ct-ZIyuK4Pcd&q=85&s=4ac89e4088465f7f2d053c89b5512247" alt="New signups manual approve" style={{backgroundColor: 'white', padding: '16px'}} width="2000" height="1150" data-path="images/developer-docs/integration/flows/new-signups-manual-v3.png" />
        </Frame>
      </Tab>

      <Tab title="3rd party vouchers">
        <Frame>
          <img src="https://mintcdn.com/mentionme/Dcv4Ct-ZIyuK4Pcd/images/developer-docs/integration/flows/new-signups-vouchers-v3.png?fit=max&auto=format&n=Dcv4Ct-ZIyuK4Pcd&q=85&s=8223c7bee6b3d1b18ae14934ce0e45a4" alt="New signups third party vouchers" style={{backgroundColor: 'white', padding: '16px'}} width="2000" height="1146" data-path="images/developer-docs/integration/flows/new-signups-vouchers-v3.png" />
        </Frame>
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

## Overview

We require a set of JavaScript tags to be installed on your website. The tags have some optional parameters which allow you to pass us the data we need such as order details and customer email and name.

<CardGroup cols={1}>
  <Card title="Referrer tag" icon="megaphone" href="/developer-docs/integration/entry-points/referrer">
    An overlay shown on the order confirmation page to promote the referral programme to existing customers or deliver retention messages.
  </Card>

  <Card title="Referee tag" icon="user-plus" href="/developer-docs/integration/entry-points/referee">
    A link on the checkout page where referred friends can enter their friend's name to claim their introductory reward.
  </Card>

  <Card title="Product Referral" icon="bag-shopping" href="/developer-docs/integration/entry-points/product-referral">
    A tag on product pages that tracks product-level sharing, identifies top advocates, and attributes revenue back to referrals.
  </Card>

  <Card title="Landing page" icon="browser" href="/developer-docs/integration/entry-points/landing-page">
    A landing page for existing customers to register into the referral programme and share with friends.
  </Card>
</CardGroup>

## Where to get help

If you need help at any time while integrating our tags, contact our [support team](https://help.mention-me.com/hc/en-gb/requests/new).
