Boletín Bien · conversion skill
backend TagHubContentService.java · ContentController.java · CategoryFeedColumn.astro · CategoryLayout.astro · ClosingSoonCard.astro (new) · LoadMoreArticles.tsx · contentParams.ts · meta.ts
Leak The hub pages (oposiciones, subvenciones) are the highest-intent surfaces, yet the default tab was "Todas", mixing closed plazos into the list, and the "Cierran pronto" deadline card lived only in the desktop rail. On mobile, where most readers arrive from Google, the rail stacks below the entire feed, so the strongest honest urgency signal was effectively invisible.
Fix Two halves. First, the backend's hub filter is now tri-state: the bare hub URL resolves automatically to the open-only view whenever the hub has open items, and falls back to the full listing when nothing is open. Explicit ?open and ?all variants exist for the toggle and stay noindexed, so the canonical URL keeps its SEO status. "Cargar más" now carries the served filter explicitly in both directions, so a "Todas" continuation can never drift into open-only pages under the new default. Second, the "Cierran pronto" card gained a mobile copy rendered above the feed, right under the filter tabs. Five new unit tests cover the auto resolution.



Metric Hub page → digest/alert opt-in rate (digestSignupSubmitted with surface "hub"), and hub bounce rate on mobile.
GazetteLayout.astro · GazetteEditionView.astro
Leak The portada foot stacked the paid "Suscríbete" card directly above the free "Apuntarme gratis" digest card, two competing primary asks in one viewport, splitting the reader's decision at the exact moment they had finished the feed.
Fix The digest capture moved mid-feed, after the first section (the same interstitial role the topic alert plays on hub pages), so each ask now owns its own viewport: the free, low-friction ask meets the reader early while they browse, and the paid card closes the page alone. An empty portada (no feed to ride) keeps the old foot placement as fallback.




Metric Per-surface subscriptionCtaClicked and digestSignupSubmitted (surface "gazette"); both should rise once they stop splitting attention.
digestOptInFlag.ts (new) · DigestOptInCta.astro · TopicAlertCta.astro · LeadOptInForm.tsx · TelegramFollowCta.astro · confirmar.ts · unsubscribe.ts
Leak The most engaged repeat visitors (digest subscribers clicking through from the daily email) were shown "Apuntarme gratis" for the exact thing they already receive, on every article, occupying the prime post-body slot. The server can never recognize them: anonymous digest subscribers have no session, and anonymous HTML is edge-cached, so any fix has to be client-side.
Fix A per-gazette localStorage mark, set by three honest signals: the opt-in form succeeding in that browser, the /confirmar success page, and any landing with utm_source=digest (only confirmed subscribers receive those links). When the mark is present, every capture card swaps client-side to the Telegram follow card. Per the owner's requirement, the /unsubscribe success page clears the mark, so a reader who leaves the list starts seeing the ask again. The mark is per gazette: joining Gipuzkoa's list never hides Valencia's ask.


Metric Telegram joins from digest-referred sessions (utm_source=digest), and the ratio of digestSignupSubmitted events that were duplicate re-submissions (should drop toward zero).
CategoryFeedColumn.astro · CategoryLayout.astro · LeadOptInForm.tsx (surface "category")
Leak Non-hub category pages offered only the paid card at the foot: membership-or-nothing for a browsing, medium-temperature reader. The commitment ladder was missing its middle rung exactly where readers explore.
Fix The generic digest capture now rides mid-feed on ordinary categories (after the fourth card, the same interstitial slot the hub alert uses), gated to non-members, with the paid card unchanged at the foot. The new "category" analytics surface makes its performance measurable on its own.


Metric digestSignupSubmitted with surface "category" (a brand-new stream, so anything above zero is lift).
daily-digest.tsx · welcome-as-lead.tsx
Leak The daily digest and the welcome email never mentioned the per-gazette Telegram channel, so the retention engine ran on a single channel. A subscriber who drifts off email had no bridge to the lighter-touch one.
Fix One quiet line after the digest sign-off and before the welcome sign-off: "¿Prefieres Telegram? Unirme al canal", the exact phrase the site already uses. A text link, never a button, so the editorial content and the welcome email's read-today CTA keep their primacy. Rendered only when the gazette has a channel wired; tests cover both the present and absent cases.


Metric Telegram channel joins attributable to email sessions, per gazette.
PaywallGate.tsx · wallHits.ts (new) · subscriptionCopy.ts · PaywallArticleLayout.astro
Leak The wall was byte-identical on the first and the fifth visit. The playbook's temperature model says the reader who keeps coming back to the wall is THE membership prospect, and the gate treated them like a stranger. The 402 payload's repeat signals went unused, and edge caching forbids any server-side branching.
Fix A client-side counter of distinct days this browser hit this gazette's wall (localStorage, per gazette, capped at 30 day-stamps). From the second distinct day on, the gate's lead swaps to an honest recognition line about the reader's own observed behavior, never a fabricated count. Every paywall_shown event now carries wall_days, so gate conversion becomes comparable by repeat state in PostHog. Wording is a functional placeholder pending an editor pass.


Metric paywall_shown → checkout_started conversion split by the new wall_days property.