Skip to content

feat(handoff): add URL-based handoff with customizable banner text#4603

Open
thomasguillot wants to merge 2 commits intotrunkfrom
feat/url-based-handoff
Open

feat(handoff): add URL-based handoff with customizable banner text#4603
thomasguillot wants to merge 2 commits intotrunkfrom
feat/url-based-handoff

Conversation

@thomasguillot
Copy link
Copy Markdown
Contributor

@thomasguillot thomasguillot commented Mar 27, 2026

All Submissions:

Context:

The handoff feature appears to have been broken on trunk for some time — the return banner doesn't seem to render at all when testing via the Components Demo. On top of that, the old implementation had become quite dated: the JS banner was embedding the old Newspack logo as a hardcoded inline SVG in CSS. This PR fixes the breakage, removes the logo entirely, and modernises the banner design and the component's API.

Changes proposed in this Pull Request:

Extends the Handoff component and ActionCard to support handing off to any arbitrary WordPress admin URL, not just Newspack-managed plugins. Previously, handoff was only possible when a managed plugin slug was available.

Key changes:

  • New url prop on Handoff component for URL-based navigation (no plugin required)
  • New handoffUrl prop on ActionCard as a convenience wrapper
  • New bannerText and bannerButtonText props on both components for customizing the return banner message
  • New POST /newspack/v1/handoff REST endpoint that stores the destination URL and banner options; validates that the URL is same-site to prevent open-redirect attacks
  • New server-side rendered handoff banner (insert_handoff_banner_static) for Newspack wizard pages where the JS banner can't render, hooked via a new newspack_before_wizard_content action
  • Handoff banner redesigned: solid primary-color background, white text, uses WP base-styles variables — old Newspack logo removed
  • The needs_handoff_return_ui() gate no longer requires setup to be incomplete — the banner now shows whenever a handoff is active
  • clear_handoff_url() extended to also clear on non-Newspack screens when a destination page was registered, preventing the banner from lingering on unrelated admin pages
  • register_handoff_for_plugin() now resets NEWSPACK_HANDOFF_DESTINATION_PAGE to prevent stale state from a prior URL-based handoff affecting subsequent plugin-based handoffs
  • PHPUnit tests added for the new REST endpoint (missing param, external URL rejection, success, unauthorized access)

How to test the changes in this Pull Request:

  1. On trunk (before this PR), navigate to Newspack > Components Demo, scroll to Handoff Buttons, and click any handoff button — confirm the return banner does not appear (verifying the pre-existing breakage).
  2. Switch to this branch and rebuild. Navigate to Newspack > Components Demo and scroll to the Handoff Buttons section.
  3. Click "Go to Dashboard" — you should be redirected to the Newspack Dashboard with a blue return banner at the top reading "Return to Components Demo once you're done."
  4. Verify the banner shows a "Dismiss" button and a "Back to Components Demo" button. Click Back — you should return to Components Demo.
  5. Repeat step 3, click "Dismiss" — the banner should disappear without navigating away.
  6. Scroll to the Action Cards section and find the "Handoff with URL" card. Click "Go to Dashboard" and verify the same banner behavior as above.
  7. Navigate to a Newspack wizard page (e.g., Settings). Trigger a handoff programmatically or via the demo and verify the static PHP-rendered banner appears at the top of the wizard page.
  8. Test an existing plugin-based handoff (e.g., Jetpack card) — confirm it still works and now accepts custom bannerText/bannerButtonText when passed.
  9. After a handoff to a non-Newspack page, navigate to an unrelated admin page (e.g., Posts) — the banner should clear and no longer be visible.
  10. After a handoff, navigate back to a Newspack page — the banner should also be gone.
  11. Verify the banner is correctly offset on pages with the WordPress admin sidebar (no overflow or misalignment).
  12. On a WooCommerce admin page, trigger a handoff and verify the banner adjusts for the WooCommerce header offset.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds URL-based “handoff” navigation (beyond managed plugins) and expands the return-banner UX so users can get back to their originating Newspack screen, including on wizard pages where the banner must be server-rendered.

Changes:

  • Add URL-based handoff support (new component props + new POST /newspack/v1/handoff endpoint).
  • Allow customizable banner body/button text across Handoff + ActionCard.
  • Redesign and re-position the handoff banner (including wizard-page static rendering and admin layout offsets).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/wizards/handoff-banner/style.scss Updates banner styling to new primary/white design and spacing vars.
src/wizards/handoff-banner/index.js Adds layout offset logic (sidebar + WooCommerce header) and supports banner text/button text via dataset.
src/wizards/componentsDemo/index.js Updates demo to exercise URL-based handoff and banner customization.
packages/components/src/handoff/index.js Adds url, bannerText, bannerButtonText props and URL-handling flow.
packages/components/src/handoff/README.md Documents new URL-based handoff and banner customization options.
packages/components/src/action-card/index.js Adds handoffUrl plus banner text props passthrough to Handoff.
includes/wizards/class-wizard.php Introduces newspack_before_wizard_content hook for wizard-page pre-content output.
includes/class-handoff-banner.php Adds server-rendered wizard banner, adjusts enqueueing, and expands stored options.
includes/api/class-plugins-controller.php Registers new /handoff REST endpoint and passes banner text options through plugin handoff.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@thomasguillot thomasguillot marked this pull request as ready for review March 27, 2026 18:58
@thomasguillot thomasguillot requested a review from a team as a code owner March 27, 2026 18:58
@thomasguillot thomasguillot added the [Status] Needs Review The issue or pull request needs to be reviewed label Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Status] Needs Review The issue or pull request needs to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants