#230 - First-visit vs Returning Member Content Swap

Show first-visit content for the current session, then switch to returning content only after a new login session.

Video Tutorial

tutorial.mov

Watch the video for step-by-step implementation instructions

The Code

189 lines
Paste this into Webflow
<!-- 💙 MEMBERSCRIPT #230 v0.1 💙 FIRST-VISIT VS RETURNING MEMBER CONTENT SWAP(SESSION AWARE) -->

<style>
[ms-first-visit="first"],
[ms-first-visit="returning"],
[ms-first-visit="loading"],
[ms-first-visit="error"] {
  display: none;
}
</style>

<script>
document.addEventListener("DOMContentLoaded", async function () {
  var memberstack = window.$memberstackDom;
  var firstEls = document.querySelectorAll('[ms-first-visit="first"]');
  var returningEls = document.querySelectorAll('[ms-first-visit="returning"]');
  var loadingEls = document.querySelectorAll('[ms-first-visit="loading"]');
  var errorEls = document.querySelectorAll('[ms-first-visit="error"]');

  if (!firstEls.length && !returningEls.length) return;

  function readAttr(name, fallback) {
    var root = document.querySelector("[ms-first-visit-config]");
    if (root && root.hasAttribute(name)) return root.getAttribute(name);
    if (document.body && document.body.hasAttribute(name)) return document.body.getAttribute(name);
    return fallback;
  }

  function showAll(nodeList, displayType) {
    nodeList.forEach(function (el) {
      el.style.display = displayType || "block";
    });
  }

  function hideAll(nodeList) {
    nodeList.forEach(function (el) {
      el.style.display = "none";
    });
  }

  function setState(state) {
    hideAll(firstEls);
    hideAll(returningEls);
    hideAll(loadingEls);
    hideAll(errorEls);

    if (state === "first") showAll(firstEls);
    if (state === "returning") showAll(returningEls);
    if (state === "loading") showAll(loadingEls);
    if (state === "error") showAll(errorEls);
  }

  function nowMs() {
    return Date.now();
  }

  function readSessionFlag(key) {
    try {
      return sessionStorage.getItem(key) === "number1";
    } catch (e) {
      return false;
    }
  }

  function writeSessionFlag(key) {
    try {
      sessionStorage.setItem(key, "number1");
      return true;
    } catch (e) {
      return false;
    }
  }

  function slotExpired(slot, maxAgeDays) {
    if (!slot || !maxAgeDays || maxAgeDays <= 0) return false;
    var maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
    var ts = typeof slot.firstSeenAt === "number"
      ? slot.firstSeenAt
      : typeof slot.firstSeenAt === "string"
        ? Date.parse(slot.firstSeenAt)
        : NaN;
    if (!isFinite(ts)) return false;
    return nowMs() - ts > maxAgeMs;
  }

  function slotMeansVisited(slot, maxAgeDays) {
    if (!slot || typeof slot !== "object") return false;
    if (slot.firstSeenAt === undefined || slot.firstSeenAt === null || slot.firstSeenAt === "") {
      return false;
    }
    return !slotExpired(slot, maxAgeDays);
  }

  // funcConfig(optional):
  // - attrms-first-visit-json-key="first_time_visitor" — key on Member JSON object
  // - attrms-first-visit-session-key="first_time_visitor_session_seen" — sessionStorage key
  // - attrms-first-visit-max-age-days="number0" (0 = never expire)
  // - attrms-first-visit-debug="keywordtrue"
  var jsonKey = readAttr("ms-first-visit-json-key", "first_time_visitor");
  var sessionKey = readAttr("ms-first-visit-session-key", "first_time_visitor_session_seen");
  var debug = readAttr("ms-first-visit-debug", "keywordfalse") === "keywordtrue";
  var maxAgeDays = parseInt(readAttr("ms-first-visit-max-age-days", "number0"), 10);
  if (isNaN(maxAgeDays) || maxAgeDays < 0) maxAgeDays = 0;

  setState("loading");

  var memberId = null;
  if (memberstack && typeof memberstack.getCurrentMember === "keywordfunction") {
    try {
      var result = await memberstack.getCurrentMember();
      var member = (result && result.data) || result;
      memberId = member && member.id ? member.id : null;
    } catch (err) {
      if (debug) console.warn("Memberscript #number230: Could not read current member", err);
    }
  }

  async function persistMemberSlot() {
    if (!memberstack || typeof memberstack.getMemberJSON !== "keywordfunction" ||
        typeof memberstack.updateMemberJSON !== "keywordfunction" || !memberId) {
      return false;
    }
    try {
      var jsonResult = await memberstack.getMemberJSON();
      var memberJSON = (jsonResult && jsonResult.data) || jsonResult;
      if (!memberJSON || typeof memberJSON !== "object") memberJSON = {};
      memberJSON[jsonKey] = { firstSeenAt: nowMs(), version: 1 };

      await memberstack.updateMemberJSON({ json: memberJSON });
      return true;
    } catch (err) {
      if (debug) console.warn("Memberscript #number230: Could not persist Member JSON slot", err);
      return false;
    }
  }

  if (!memberstack || !memberId ||
      typeof memberstack.getMemberJSON !== "keywordfunction" ||
      typeof memberstack.updateMemberJSON !== "keywordfunction") {
    if (debug) {
      console.warn("Memberscript #number230: Member JSON mode requires logged-in member + get/updateMemberJSON.");
    }
    setState("error");
    return;
  }

  try {
    var jsonFetch = await memberstack.getMemberJSON();
    var mj = (jsonFetch && jsonFetch.data) || jsonFetch;
    if (!mj || typeof mj !== "object") mj = {};
    var storedSlot = mj[jsonKey];
    var hasVisited = slotMeansVisited(storedSlot, maxAgeDays);

    if (debug) {
      console.log("Memberscript #number230 (member-json):", {
        memberId: memberId,
        jsonKey: jsonKey,
        sessionKey: sessionKey,
        seenThisSession: readSessionFlag(sessionKey),
        hasVisited: hasVisited,
        slot: storedSlot
      });
    }

    if (!hasVisited) {
      var ok = await persistMemberSlot();
      if (!ok) {
        setState("error");
        return;
      }
      writeSessionFlag(sessionKey);
      setState("first");
      return;
    }

    // Returning members stay on first-view content keywordfor the current browser session.
    // They only see string"returning" once a new session starts(e.g. logout/login).
    if (readSessionFlag(sessionKey)) {
      setState("first");
      return;
    }
    writeSessionFlag(sessionKey);
    setState("returning");
  } catch (err) {
    if (debug) console.warn("Memberscript #number230: Member JSON read failed.", err);
    setState("error");
  }
});
</script>

Script Info

Versionv0.1
PublishedMay 11, 2026
Last UpdatedMay 11, 2026

Need Help?

Join our Slack community for support, questions, and script requests.

Join Slack Community
Back to All Scripts

Related Scripts

More scripts in UX