Use this doc to verify all changes from the “subscribe URL centralized + GateCard emailMode + subscribe-direct hub API” commit.
All links are absolute paths — click to open the exact line in VS Code.
What changed: /subscribe-direct is now defined once in AppCoreConfig. All callers read from it.
| What | Link |
|---|---|
subscribeUrl: '/subscribe-direct' added to AppCoreConfig defaults |
assets/js/app-core.js:45 |
SUBSCRIBE_URL constant derived from config |
assets/js/app-core.js:52 |
requestNotificationPermission() uses SUBSCRIBE_URL |
assets/js/app-core.js:350 |
updateUI() redirect uses SUBSCRIBE_URL |
assets/js/app-core.js:360 |
Paywall CTA link uses SUBSCRIBE_URL |
assets/js/app-core.js:562 |
How to verify:
# Should return ZERO results — no raw /subscribe-direct strings left in app-core.js
grep -n "'/subscribe-direct'\|\"\/subscribe-direct\"" assets/js/app-core.js
How to change the subscribe URL site-wide:
Edit only subscribeUrl at line 45. Everything else follows.
emailMode option + inline form supportWhat changed: GateCard now supports emailMode: 'form' which renders an inline EmailSubscribe form instead of a link.
| What | Link |
|---|---|
emailMode in JSDoc comment |
assets/js/ui/subscribe/GateCard.js:13 |
_subscribeUrl() helper reads AppCoreConfig.subscribeUrl |
assets/js/ui/subscribe/GateCard.js:23 |
emailMode default in _defaults() |
assets/js/ui/subscribe/GateCard.js:78 |
emailUrl default reads _subscribeUrl() |
assets/js/ui/subscribe/GateCard.js:85 |
render() calls _injectEmailForm when emailMode:'form' |
assets/js/ui/subscribe/GateCard.js:58 |
wire() also calls _injectEmailForm |
assets/js/ui/subscribe/GateCard.js:72 |
_emailSlot() — returns form placeholder or link |
assets/js/ui/subscribe/GateCard.js:133 |
_injectEmailForm() — injects EmailSubscribe, polls 150ms, falls back to link |
assets/js/ui/subscribe/GateCard.js:141 |
_showEmailFollowUp() — branches on emailMode (form vs link) |
assets/js/ui/subscribe/GateCard.js:203 |
How to use on any page:
// Show inline email form instead of link (gate modal):
GateCard.render(container, { mode: 'sequential', emailMode: 'form' });
// Show push button only:
GateCard.render(container, { mode: 'push-only' });
// Show both push + email form side-by-side:
GateCard.render(container, { mode: 'both', emailMode: 'form' });
Front matter shortcuts (post.html):
gate_mode: sequential # sequential | push-only | email-only | both
gate_email_mode: form # link | form
gate_email_url: /custom-subscribe # override URL for this post only
post.html GATE_CONFIG — emailMode + URL from configWhat changed: GATE_CONFIG now exposes emailMode and reads emailUrl from AppCoreConfig instead of hardcoding it.
| What | Link |
|---|---|
| GATE_CONFIG block with all options | _layouts/post.html:888 |
emailMode field (front matter: gate_email_mode) |
_layouts/post.html:896 |
emailUrl reads AppCoreConfig.subscribeUrl as fallback |
_layouts/post.html:897 |
bookpost.html SUBSCRIPTION_INTENTS — URL from configWhat changed: fallbackUrl in both intents now reads AppCoreConfig.subscribeUrl instead of /subscribe-direct hardcoded.
| What | Link |
|---|---|
_subUrl() helper |
_layouts/bookpost.html:2130 |
chapterByPush.fallbackUrl uses _subUrl |
_layouts/bookpost.html:2132 |
bookPdfDownload.fallbackUrl uses _subUrl |
_layouts/bookpost.html:2134 |
subscribe-direct.html — new hub API throughoutWhat changed: page now uses SubscriptionHub for cap checks and sends full grants on push subscribe.
| What | Link |
|---|---|
Load subscription-hub.js as ESM → window.SubscriptionHub |
subscribe-direct.html:174 |
FULL_PUSH_GRANTS constant defined inline |
subscribe-direct.html:179 |
Early return uses hasCap('read') not localStorage |
subscribe-direct.html:223 |
subscribeFor({ grants: FULL_PUSH_GRANTS }) instead of bare subscribe() |
subscribe-direct.html:256 |
On-load check uses hasCap('read') not localStorage |
subscribe-direct.html:302 |
How to verify:
# Should return ZERO — no direct localStorage push reads left
grep -n "localStorage.*push_subscribed" subscribe-direct.html
# Should return FULL_PUSH_GRANTS — not bare subscribe()
grep -n "subscribeFor\|subscribe()" subscribe-direct.html
cd /home/ahmed/.gemini/antigravity/scratch/ahmedbouchefra2
# 1. No raw /subscribe-direct strings in app-core.js (only SUBSCRIBE_URL)
grep -n "'/subscribe-direct'\|\"\/subscribe-direct\"" assets/js/app-core.js
# 2. No localStorage push reads in subscribe-direct page
grep -n "localStorage.*push_subscribed" subscribe-direct.html
# 3. GateCard reads URL from config, not hardcoded
grep -n "subscribe-direct" assets/js/ui/subscribe/GateCard.js
# 4. bookpost fallbackUrl uses _subUrl helper
grep -n "fallbackUrl" _layouts/bookpost.html
# 5. post.html GATE_CONFIG has emailMode field
grep -n "emailMode" _layouts/post.html
All checks should return either zero results or show the new patterns (no raw /subscribe-direct strings, no localStorage.getItem('push_subscribed')).