// Flodesk integration — loads the universal Flodesk script IMMEDIATELY // (not inside a React effect) so that window.fd is available before any // component mounts. Both the header-popup form and the inline newsletter // form rely on this being ready at first render. // // Adapted for the Babel-in-browser JSX setup this project uses (no module // system, components are attached to `window`). // ─── Form IDs ────────────────────────────────────────────────────────── // Two separate Flodesk forms — popup for the header RSVP button, inline // for the newsletter section at the bottom of the page. If either ID is // wrong, grab the correct one from your Flodesk dashboard's embed code // and update just the line below. window.FLODESK_FORM_ID_POPUP = '6a167e11dbcc2ba4d142227f'; window.FLODESK_FORM_ID_INLINE = '6a1682b16ac1cb0c79456589'; // ─── Load the Flodesk universal script (runs once, on first parse) ───── (function loadFlodesk(w, d, t, h, s, n) { if (w[n]) return; // already loaded w.FlodeskObject = n; // Queue shim: any calls to window.fd(...) before the real script // finishes loading are pushed onto window.fd.q and replayed. var fn = function () { (w[n].q = w[n].q || []).push(arguments); }; w[n] = fn; var f = d.getElementsByTagName(t)[0]; var v = '?v=' + Math.floor(new Date().getTime() / (120 * 1000)) * 60; var sm = d.createElement(t); sm.async = true; sm.type = 'module'; sm.src = h + s + '.mjs' + v; f && f.parentNode && f.parentNode.insertBefore(sm, f); var sn = d.createElement(t); sn.async = true; sn.noModule = true; sn.src = h + s + '.js' + v; f && f.parentNode && f.parentNode.insertBefore(sn, f); })(window, document, 'script', 'https://assets.flodesk.com', '/universal', 'fd'); // ─── Register the popup form immediately ─────────────────────────────── // Queue shim above makes this safe to call even before the script lands. window.fd('form', { formId: window.FLODESK_FORM_ID_POPUP }); // ─── React component: also (re)registers the popup in case the page // was rendered after Flodesk loaded but before the queued init ran. // Rendering nothing keeps the popup invisible until openClubSignup(). const { useEffect: useEffectFD } = React; function FlodeskPopup() { useEffectFD(() => { // Safe — window.fd is always defined by now (queue shim or real). window.fd('form', { formId: window.FLODESK_FORM_ID_POPUP }); }, []); return null; } Object.assign(window, { FlodeskPopup }); // ─── Shared helper for RSVP buttons ──────────────────────────────────── // Behavior chosen by the author: every "RSVP to the Club" button across // the site routes readers to the EMBEDDED Flodesk form at the bottom of // the page (or the homepage if we're elsewhere) rather than opening a // popup. The popup form ID is kept for future use / a manual trigger but // is no longer the default click target. window.openClubSignup = function openClubSignup() { var el = document.getElementById('newsletter'); if (el && typeof el.scrollIntoView !== 'undefined') { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); // Once scrolled, try to focus the first input inside the embedded form. setTimeout(function () { var inlineId = window.FLODESK_FORM_ID_INLINE || ''; var sel = inlineId ? ('#fd-form-' + inlineId + ' input') : '.er-newsletter input'; var input = document.querySelector(sel) || document.querySelector('.er-newsletter input'); if (input && typeof input.focus === 'function') input.focus(); }, 700); return; } // If we're not on a page that has #newsletter (privacy, links, etc.), // jump to the homepage with the anchor. window.location.href = 'index.html#newsletter'; };