The problem
I wanted to turn blog posts into lead magnets without building a separate landing page for each one. The blog already renders MDX. The subscribe API already writes to Supabase and Kit. I needed a way to gate specific sections of a post behind an email form, inline, without breaking the reading flow.
How it works
The EmailGate component wraps any chunk of MDX content. Readers see the ungated content above it, then a glassmorphic card with an email input. After they submit, the gated content appears and localStorage remembers them so they never see the form again on that post.
The component takes two props:
| Prop | What it does |
|---|---|
slug | Matches the blog post filename. Gets sent to /api/subscribe as the source tag. |
preview | Optional teaser text shown above the gate form. |
On submit, the API upserts the email into the email_subscribers table in Supabase (deduplicated by email + slug) and creates a lead-magnet:[slug] tag in Kit. Both happen in a single request. If Kit is down, the Supabase write still succeeds.
The MDX wiring
The blog renderer uses next-mdx-remote with a components map. I registered EmailGate and EmailSignup as available MDX components so any blog post can use them:
const mdxComponents = {
// ...all the styled HTML overrides...
EmailGate,
EmailSignup,
};
In the MDX file, the syntax is:
<EmailGate slug="post-slug" preview="A teaser shown above the form.">
## Gated content here
This section is hidden until the reader submits their email.
</EmailGate>
No config files. No build step. Drop the component into the post and it works.
The section below covers the specific implementation decisions and what I'd change next time.
Keep reading
Enter your email to see the rest of this post.
The pipeline
This component is one piece of the /publish skill pipeline: write post, gate it, deploy, set up Instagram comment-to-DM automation, output a Reel caption. Each step feeds the next. The blog post becomes the destination URL in the DM. The email gate captures the lead. The Reel drives traffic.
One session, one component, and blog posts now double as lead magnets.