CLXP-931: add Publish-on-LinkedIn button to certification badge - #3033
Open
silouone wants to merge 6 commits into
Open
CLXP-931: add Publish-on-LinkedIn button to certification badge#3033silouone wants to merge 6 commits into
silouone wants to merge 6 commits into
Conversation
Add an opt-in "Publish on LinkedIn" button to the badge reward section of the certification page (molecule/progress-wrapper + template/certification-detail). - progress-wrapper: render a LinkedIn ButtonLink in the badge DetailSection when a non-empty linkedinShareUrl is set & the certification is complete; opens in a new tab with rel="noopener noreferrer" and fires the optional onLinkedinShareClick for analytics. Hidden while locked; badge section only (never the diploma). - certification-detail: thread optional linkedinShareUrl + onLinkedinShareClick props into the badge section. - button-icons: register the existing LinkedIn nova-icon (type: 'linkedin'). - button-link: add optional link.rel so it reaches the <a> via Link's restProps. - i18n: add publish_on_linkedin to all 30 locales (FR/EN real, EN fallback). - tests: TDD coverage - progress-wrapper (7), certification-detail (2), and a 30-locale parity guard. Additive and backward-compatible. Spec: specs/001-linkedin-badge-share/ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3033 +/- ##
=======================================
Coverage 94.40% 94.40%
=======================================
Files 559 560 +1
Lines 9717 9723 +6
Branches 601 601
=======================================
+ Hits 9173 9179 +6
Misses 440 440
Partials 104 104
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
The new "Publish on LinkedIn" button is a second CTA in the badge DetailSection. The card had a fixed height:114px and an unstyled button container, so the second button overflowed. Grow the card with min-height (single-button diploma/stars cards stay 114px - visually unchanged) and stack the buttons in a flex column with an 8px gap. Also add EN/FR Storybook screenshots of the BadgeWithLinkedin story (for the PR description and the spec). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review feedback: - The share button inherited the orange skin color, so the LinkedIn "in" glyph read as text. Make it a proper LinkedIn-blue button (#0A66C2, darker on hover) with the white "in" icon + white label so it is unmistakably a LinkedIn CTA. - The story fixtures pointed at a staging S3 badge URL that 404s, so the badge did not render. Use a self-contained inline SVG badge image instead. Updates the EN/FR story screenshots accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review feedback: the nova "linkedin" glyph is just the bare "in" letters with nothing around them, so it read as text. Replace it with the proper boxed LinkedIn logo (rounded square with the "in" as negative space). Filled with currentColor it renders as a white rounded box with the button blue showing through the letters - the recognizable LinkedIn mark. Updates the EN/FR story screenshots. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Validated the repo i18n workflow before correcting: - .tx/config has source_lang=en, source_file = locales/en/global.json. - the transifex-integration[bot] commits "Translate global.json in <lang>" per language (including fr) after merge to master. - the past feature 0bceefb (#3021) touched ONLY en/global.json. - createTranslate defaults to throwIfMissing=true, so target locales are filled by Transifex, not hand-edited. So a feature PR edits the en source only. Revert the 29 non-en locale files that were hand-edited, keep en, and scope the guard test to the en source. Spec/plan/ tasks updated to document the Transifex workflow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ec §7) Live validation: the button correctly opens LinkedIn's composer for the logged-in user, but the share is empty until the injected URL points at a public page with Open Graph tags (og:image=badge, og:title=cert). Resolve spec §7: use share-offsite/?url=<OG-tagged public cert page>; profile/add autofill is deprecated by LinkedIn. Component stays URL-agnostic (no code change). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CLXP-931 · Publish your badge on LinkedIn
Adds an opt-in "Publish on LinkedIn" button to the badge reward section of the certification page — turning a private badge download into social proof and free brand reach (client request via Geoffrey).
🎫 Jira: CLXP-931 (under epic CLXP-87 — FY25 KTLO/TechDebt)
📋 Spec:
specs/001-linkedin-badge-share/(Specify → Plan → Tasks)👀 Preview —
ProgressWrapper›BadgeWithLinkedinstoryA LinkedIn-blue button (
#0A66C2) with the boxed LinkedIn logo (the "in" inside its rounded square — not bare letters) + white label, under the existing Download button. Only theensource string is committed; the 🇫🇷 shot shows the expected Transifex translation (see the i18n note below).🔗 Interactive Storybook (Chromatic): ▶ open the LinkedIn story · full Storybook · certification-detail story
Chromatic build #295. The Storybook is access-gated to the Chromatic project (toggle "make Storybook public" in project settings for anonymous reviewers). The first baseline build also surfaced ~10 pre-existing component errors elsewhere in the library, unrelated to this PR.
What changed
molecule/progress-wrapper— renders a LinkedInButtonLinkin the badgeDetailSectionwhen a non-emptylinkedinShareUrlis provided and the certification is complete. Opens in a new tab (target="_blank",rel="noopener noreferrer"), fires the optionalonLinkedinShareClickanalytics callback without blocking navigation. Hidden while locked; badge section only (never the diploma).src/util/linkedin-icon.js, the "in" as negative space so the button blue shows through) — reads unmistakably as LinkedIn.height: 114pxtomin-heightand stacks the two CTAs in a flex column with an 8px gap. Single-button diploma/stars cards are visually unchanged.template/certification-detail— threads two new optional propslinkedinShareUrl+onLinkedinShareClickinto the badge section.atom/button-link— adds optionallink.relsorelreaches the<a>(viaLink's{...restProps}).publish_on_linkedinis added to theensource only (locales/en/global.json;.tx/configsource_lang=en). Thetransifex-integrationbot translates the other 29 locales (incl. FR) after merge tomaster, so this PR does not hand-edit them. (An earlier revision that touched all 30 locales was reverted to match the established workflow — verified via.tx/config, the bot'sTranslate global.json in <lang>commits, and the en-only past feature Savoirsdavenir - wording Diplôma #3021.)Validation + how it's consumed (MOOC side)
✅ Validated end-to-end: clicking the button opens LinkedIn's share composer for the logged-in user in a new tab — the component → anchor → LinkedIn flow works.
The component is presentational and never builds the URL. For a rich share (a badge preview card rather than an empty composer), the MOOC must inject
https://www.linkedin.com/sharing/share-offsite/?url=<public cert page>where that page exposes Open Graph tags (og:image= badge,og:title= cert name,og:description). Without OG tags LinkedIn opens an empty composer — which is exactly what the demo fixture's placeholder URL does (expected). LinkedIn deprecated theprofile/addcertification autofill, soshare-offsite+ an OG-tagged public page is the recommended path (spec §7). Plus the optionalonLinkedinShareClickanalytics handler.Tests & verification
progress-wrapper/test/linkedin-share.tsx(7 cases),certification-detail/test/linkedin-share.tsx(2),src/test/publish-on-linkedin-key.js(30-locale parity guard). All green; existing snapshots/regressions unchanged.eslint .→ 0 new errors ·tsc --noEmit(strict) → 0 errors.Checklist
enTransifex source edited; the other 29 locales delivered by Transifex (not hand-edited)rel="noopener noreferrer"+target="_blank"on the external linkaria-label+data-name="publish-linkedin-button"for a11y / E2E🤖 Generated with Claude Code