diff --git a/index.mdx b/index.mdx index 3d7b152..bc50e9f 100644 --- a/index.mdx +++ b/index.mdx @@ -9,6 +9,7 @@ description: "Build Mini Apps, integrate World ID, and deploy on World Chain wit --- import { DeveloperStories } from "/snippets/developer-stories.jsx"; +import { NewsletterForm } from "/snippets/newsletter-form.jsx"; {/* cspell:ignore worldcoin Estevez Jangwon Toktokhan Hyrax gigagas flashblock prismic */} @@ -134,35 +135,10 @@ import { DeveloperStories } from "/snippets/developer-stories.jsx";
- {/* Newsletter — uncomment when a subscribe endpoint exists. - Why it is disabled: world.org's form submits through a Next.js server - action (company-website src/actions/subscribe.ts) that calls Braze with - the server-side NEXT_SERVER_BRAZE_TOKEN. A static Mintlify site cannot - hold that secret, so this form needs either a public subscribe endpoint - from the web team or a Braze public-key integration before it can ship. - Endpoint proposed as https://github.com/worldcoin/company-website/pull/4481 — - once merged (plus its Cloudflare rate rule), point this form at - POST https://world.org/api/subscribe with body {email} and uncomment. - -
-
-
- Subscribe to World Developers Newsletter -
-
-
- - -
-
- By entering your email address and clicking “Subscribe,” you consent to receive newsletters, marketing communications and ecosystem updates. For details on how we process your personal data, including your rights and how to exercise them, please review our Privacy Notice. -
-
-
-
- */} + {/* Newsletter — submits to world.org's public subscribe endpoint + (worldcoin/company-website#4481). If that endpoint is not live yet, + the form shows an explicit error instead of failing silently. */} + {/* Footer links — single row per Docs 3.0: trademark left, links right */}
diff --git a/snippets/newsletter-form.jsx b/snippets/newsletter-form.jsx new file mode 100644 index 0000000..7c8f302 --- /dev/null +++ b/snippets/newsletter-form.jsx @@ -0,0 +1,90 @@ +/** + * "Subscribe to World Developers Newsletter" block for the landing footer, + * per the Docs 3.0 design. Submits to world.org's public subscribe endpoint + * (worldcoin/company-website#4481). Single attempt with a bounded timeout and + * explicit success/error states — no silent failures, no retries (subscribing + * twice on a retry would double-fire the marketing pipeline). + * Mintlify-safe: single exported component, no top-level helpers, no refs. + */ +import { useState } from "react"; + +export const NewsletterForm = ({ endpoint = "https://world.org/api/subscribe" }) => { + const [status, setStatus] = useState("idle"); // idle | loading | ok | error + + const onSubmit = async (event) => { + event.preventDefault(); + if (status === "loading") return; + const input = event.currentTarget.querySelector("input[type=email]"); + const email = (input && input.value ? input.value : "").trim(); + if (!email || !input.checkValidity()) { + setStatus("error"); + return; + } + setStatus("loading"); + const abort = new AbortController(); + const timer = setTimeout(() => abort.abort(), 10000); + try { + const res = await fetch(endpoint, { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ email }), + signal: abort.signal, + }); + setStatus(res.ok ? "ok" : "error"); + } catch (_) { + setStatus("error"); + } finally { + clearTimeout(timer); + } + }; + + return ( +
+
+
+ Subscribe to World Developers Newsletter +
+
+ {status === "ok" ? ( +
+ Thanks — you’re subscribed. +
+ ) : ( +
+ + +
+ )} + {status === "error" ? ( +
+ Something went wrong — check the address and try again. +
+ ) : null} + {status !== "ok" ? ( +
+ By entering your email address and clicking “Subscribe,” you consent to receive newsletters, marketing communications and ecosystem updates. For details on how we process your personal data, including your rights and how to exercise them, please review our Privacy Notice. +
+ ) : null} +
+
+
+ ); +}; + +export default NewsletterForm; diff --git a/tailwind.css b/tailwind.css index d3bd1ae..bb536ae 100644 --- a/tailwind.css +++ b/tailwind.css @@ -286,6 +286,13 @@ .dark .landing-email-input::placeholder { color: #75726F; } + @media (max-width: 900px) { + /* Newsletter stacks on small screens (the grid is inline-styled). */ + .landing-newsletter > div { + grid-template-columns: 1fr !important; + gap: 32px !important; + } + } .landing-privacy-link { color: #2D2C2C !important; }