Skip to content

🐛 Fixed missing gift link option in the share modal for pages#28988

Draft
jonatansberg wants to merge 2 commits into
mainfrom
ber-3751-gift-link-share-modal-for-pages
Draft

🐛 Fixed missing gift link option in the share modal for pages#28988
jonatansberg wants to merge 2 commits into
mainfrom
ber-3751-gift-link-share-modal-for-pages

Conversation

@jonatansberg

@jonatansberg jonatansberg commented Jun 30, 2026

Copy link
Copy Markdown
Member

closes NY-1401

Problem

The "Share as a gift" option showed in the analytics share modal for posts but not for pages. As the reporter noted, there was no explicit guard — it was a side-effect of how the resource is fetched.

Pages reach the same React analytics screen as posts (the pages list links to #/posts/analytics/:id). But post-analytics-context resolved the resource only via useBrowsePosts, and the /posts/ endpoint never returns pages. So for a page, post came back undefineduseCanManageGiftLink(post) short-circuited on !post → the gift option (and the post title/preview) was hidden.

Confirmed live: GET /posts/?filter=id:<pageId> → 0 results; GET /pages/?filter=id:<pageId> → the page with status: published, visibility: members.

Fix

  • post-analytics-context.tsx — when the posts lookup is empty, fall back to useBrowsePages and expose postType: 'post' | 'page'. The fallback only fires when the post query returns nothing, so post analytics is unaffected.
  • constants.ts — added PAGE_ANALYTICS_INCLUDE; the pages API rejects the post-only includes (email, newsletter, click/feedback counts), so the page lookup requests the allowed subset.
  • post-analytics-header.tsx — pass resource to GiftLinkModal so it queries the right endpoint (it defaulted to posts, which would have failed for a page even once shown).
  • test-helpers.ts — replaced a junk postType object in the mock fixture (wrong shape, slipped in when the type had no postType) with 'post'.

Verification

  • Live in the admin: the share modal on a published members-only page now shows "Share as a gift", the preview hydrates the page's real title/excerpt/author, and clicking through generates a working gift link (/private-page/?gift=…).
  • Tests: added a provider regression test (post resolves as post; empty posts → pages fallback resolves as page with visibility). Full posts suite passing (486), lint clean.

Follow-up (not in this PR)

A few labels still hardcode "post" and read oddly for pages (the gift teaser "members-only post", the "Post analytics" breadcrumb, the "Your post is published" success title). These live in shared/shade components and are a pre-existing naming gap, so this PR stays scoped to the actual bug.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2a659f68-103f-41b9-8ec9-81fdd78bdc85

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ber-3751-gift-link-share-modal-for-pages

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 29f1aaa

Command Status Duration Result
nx run @tryghost/admin-x-settings:test:acceptance ✅ Succeeded 10m 56s View ↗
nx run-many --target=build --projects=tag:publi... ✅ Succeeded 1s View ↗
nx run-many -t test:unit -p @tryghost/posts,@tr... ✅ Succeeded 7m 27s View ↗
nx run @tryghost/admin:build ✅ Succeeded 4m 27s View ↗
nx run ghost-admin:test ✅ Succeeded 3m 12s View ↗
nx run-many -t lint -p @tryghost/posts,@tryghos... ✅ Succeeded 1m 10s View ↗
nx run @tryghost/activitypub:test:acceptance ✅ Succeeded 57s View ↗
nx run ghost:build:assets ✅ Succeeded 2s View ↗
nx run ghost:build:tsc ✅ Succeeded 6s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-06-30 12:47:55 UTC

@jonatansberg jonatansberg force-pushed the ber-3751-gift-link-share-modal-for-pages branch from 0121eeb to 26be980 Compare June 30, 2026 11:57
closes https://linear.app/ghost/issue/BER-3751

- pages reach the same analytics share modal as posts, but the context resolved the resource only via the posts endpoint, which never returns pages
- so a page came back undefined and the gift-link eligibility check (which reads status/visibility) silently failed, hiding the option
- fall back to the pages endpoint when the post lookup is empty, and pass the resolved resource through to the gift-link modal
ref https://linear.app/ghost/issue/BER-3751

- pages share the post analytics screen, so its breadcrumb, share modal, edit/delete actions and delete dialog all referred to a page as a "post"
- derive the noun from the resolved resource type and thread it through PostShareModal (new optional resourceNoun prop, defaulting to "post" so posts are unchanged)
- also corrects the edit action to open the page editor route rather than the post editor
@jonatansberg jonatansberg force-pushed the ber-3751-gift-link-share-modal-for-pages branch from 26be980 to 29f1aaa Compare June 30, 2026 12:34
@cmraible cmraible self-requested a review June 30, 2026 22:13

@cmraible cmraible left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really agree with this approach. Currently page analytics only works at all by accident, and I'd prefer a more holistic solution than falling back to the pages API if the posts request fails. Specifically, the route for page analytics should be /pages/analytics/{id} rather than /posts/analytics/{id}. This way we could use the routing itself to determine whether to hit the posts or pages endpoints, includes, etc. and save the additional round trip to the API and eliminate this fallback logic.

As I understand it, getting page analytics working isn't a blocker for shipping gift links, so I'd prefer not to merge this in favor of waiting for a more holistic solution that actually gets page analytics fully working properly.

Copy link
Copy Markdown
Member Author

This PR started as fix the modal, then fix the copy, and you could definitely expand from there to also fix the routing. That would make sense.

I might have some time later this week or next week where I could get this fixed. Is there anything else beyond the routing that you feel is missing to make this work properly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants