Skip to content

Commit 8ea8267

Browse files
feat: clearer share CTA + track readme_badge_copied + mobile auto-scroll
Three small changes to make the share flow visible in analytics (share_clicked is currently absent from the top events list). 1. CTA text: "Share certificate" -> "Share to X / Instagram" (desktop) and "Share as Story" -> "Post obituary on X" (mobile). Verb + platform tells visitors what the button actually does. 2. Track readme_badge_copied on the README badge copy button so we can measure GEO backlink spread (every copied badge is a potential inbound link from a GitHub repo). 3. After certificate reveals on mobile, smooth-scroll the share/download row into view so the primary CTA is visible without manual scroll. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 69db237 commit 8ea8267

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

src/components/CertificateCard.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export default function CertificateCard({ cert, onReset }: Props) {
9696
const wrapperRef = useRef<HTMLDivElement>(null)
9797
const visibleStampRef = useRef<HTMLDivElement>(null)
9898
const exportStampRef = useRef<HTMLDivElement>(null)
99+
const actionsRef = useRef<HTMLDivElement>(null)
99100
const [referrerUser, setReferrerUser] = useState<string | null>(null)
100101

101102
useEffect(() => {
@@ -153,6 +154,16 @@ export default function CertificateCard({ cert, onReset }: Props) {
153154
return () => cancelAnimationFrame(id)
154155
}, [])
155156

157+
useEffect(() => {
158+
if (!visible || !isMobileViewport || !actionsRef.current) return
159+
// After the certificate reveals, nudge the share/download row into view
160+
// so the primary CTA is visible without manual scroll.
161+
const id = window.setTimeout(() => {
162+
actionsRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })
163+
}, 600)
164+
return () => window.clearTimeout(id)
165+
}, [visible, isMobileViewport])
166+
156167
useEffect(() => {
157168
if (typeof window === 'undefined') return
158169
const applyScale = () => {
@@ -467,7 +478,7 @@ export default function CertificateCard({ cert, onReset }: Props) {
467478
</div>
468479

469480
{/* ── Actions below certificate ── */}
470-
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', width: '100%' }}>
481+
<div ref={actionsRef} style={{ display: 'flex', flexDirection: 'column', gap: '8px', width: '100%' }}>
471482

472483
{/* Share + Download — side by side */}
473484
{!showInlineShare && (
@@ -486,7 +497,7 @@ export default function CertificateCard({ cert, onReset }: Props) {
486497
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px',
487498
}}
488499
>
489-
{isGeneratingShare || isDownloading ? <span className="btn-spinner" /> : (isMobileViewport ? 'Share as Story' : 'Share certificate')}
500+
{isGeneratingShare || isDownloading ? <span className="btn-spinner" /> : (isMobileViewport ? 'Post obituary' : 'Post on X / Instagram')}
490501
</button>
491502
<button
492503
type="button"
@@ -649,6 +660,7 @@ export default function CertificateCard({ cert, onReset }: Props) {
649660
<button
650661
type="button"
651662
onClick={async () => {
663+
track('readme_badge_copied')
652664
const ok = await copyText(badgeMd)
653665
if (!ok) promptCopy(badgeMd, 'Copy this README badge markdown')
654666
setBadgeCopied(true)
@@ -660,7 +672,7 @@ export default function CertificateCard({ cert, onReset }: Props) {
660672
</button>
661673
</div>
662674
<p className="readme-badge-caption cert-readme-caption" style={{ fontFamily: MONO }}>
663-
↻ paste once updates automatically
675+
↻ paste once, updates automatically
664676
</p>
665677
</div>
666678
</div>

0 commit comments

Comments
 (0)