Conversation
There was a problem hiding this comment.
Pull request overview
Adds Send Tab–specific UI variants and improves success-banner handling for /pair and /pair/auth/complete across both the React (fxa-settings) and Backbone (fxa-content-server) implementations, using origin-driven messaging when Pair routes are React-enabled.
Changes:
- Update Sync navigation logic to soft-navigate to React
/pairwithlocation.state.origin, while keeping Backbone/pairon hard-nav + query params. - Implement Send Tab variants for
/pairand/pair/auth/complete(React + Backbone) with updated headings/copy and suppressed CTAs where required. - Add/expand tests and Storybook stories for new banner variants and Send Tab layouts; add shared Send Tab entrypoint constants in content-server.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/fxa-settings/src/pages/Signup/ConfirmSignupCode/index.tsx | Uses integration entrypoint to detect Send Tab and passes location.state when navigating to React /pair. |
| packages/fxa-settings/src/pages/Signin/utils.ts | Adds config-based branching for /pair navigation and switches Send Tab detection to use entrypoint value directly. |
| packages/fxa-settings/src/pages/Signin/utils.test.ts | Updates tests for entrypoint-based Send Tab detection and React /pair soft-nav with origin state. |
| packages/fxa-settings/src/pages/Pair/Index/index.tsx | Renders success banners based on location.state.origin and adds Send Tab choice-screen variant. |
| packages/fxa-settings/src/pages/Pair/Index/index.test.tsx | Adds coverage for origin-driven banners and Send Tab choice-screen rendering. |
| packages/fxa-settings/src/pages/Pair/Index/index.stories.tsx | Adds stories for new banner variants and Send Tab choice screen. |
| packages/fxa-settings/src/pages/Pair/Index/en.ftl | Adds new strings for banner variants and Send Tab heading; updates CAD header id/string. |
| packages/fxa-settings/src/pages/Pair/AuthComplete/index.tsx | Adds Send Tab-specific AuthComplete layout and device-connected copy. |
| packages/fxa-settings/src/pages/Pair/AuthComplete/index.test.tsx | Adds tests ensuring Send Tab variant renders and suppresses CTAs. |
| packages/fxa-settings/src/pages/Pair/AuthComplete/index.stories.tsx | Adds Send Tab variant story using a minimal integration stub. |
| packages/fxa-settings/src/pages/Pair/AuthComplete/en.ftl | Adds Send Tab variant strings for AuthComplete. |
| packages/fxa-settings/src/models/mocks.tsx | Extends createHistoryWithQuery to support reach-router location state for stories. |
| packages/fxa-settings/src/components/App/index.tsx | Passes integration through to the React /pair route. |
| packages/fxa-content-server/app/tests/spec/views/pair/index.js | Adds Backbone /pair test coverage for Send Tab variant + description suppression. |
| packages/fxa-content-server/app/tests/spec/views/pair/auth_complete.js | Adds Backbone AuthComplete tests for Send Tab vs default variants. |
| packages/fxa-content-server/app/scripts/views/pair/index.js | Sets isSendTab in view context based on entrypoint for Backbone template branching. |
| packages/fxa-content-server/app/scripts/views/pair/auth_complete.js | Sets isSendTab based on relier/query entrypoint for Backbone AuthComplete branching. |
| packages/fxa-content-server/app/scripts/templates/pair/index.mustache | Adds Send Tab choice-screen markup and suppresses description paragraph in Send Tab flow. |
| packages/fxa-content-server/app/scripts/templates/pair/auth_complete.mustache | Adds Send Tab AuthComplete variant (no CTA, different copy). |
| packages/fxa-content-server/app/scripts/lib/constants.js | Adds SEND_TAB_ENTRYPOINTS list (kept in sync with settings). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import { isSendTabEntrypoint } from '../../Signin/utils'; | ||
| import type { PairOrigin } from '../../Signin/utils'; | ||
| import type { SigninLocationState } from '../../Signin/interfaces'; | ||
| import type { Integration } from '../../../models'; | ||
|
|
There was a problem hiding this comment.
This page imports isSendTabEntrypoint from pages/Signin/utils, which also pulls in a large set of sign-in navigation/auth dependencies (e.g., navigate, hardNavigate, session hooks, config). This creates an unnecessary coupling and may bloat the Pair bundle. Consider extracting isSendTabEntrypoint into a small shared module (e.g., alongside SEND_TAB_ENTRYPOINTS in src/constants or a dedicated sendTab util) and importing it from there in both Pair and Signin.
| import { isSendTabEntrypoint } from '../../Signin/utils'; | |
| import type { PairOrigin } from '../../Signin/utils'; | |
| import type { SigninLocationState } from '../../Signin/interfaces'; | |
| import type { Integration } from '../../../models'; | |
| import type { Integration } from '../../../models'; | |
| type PairOrigin = 'signin' | 'signup' | 'post-verify-set-password'; | |
| type SigninLocationState = { | |
| origin?: PairOrigin; | |
| }; | |
| const isSendTabEntrypoint = (entrypoint?: string | null) => | |
| typeof entrypoint === 'string' && | |
| entrypoint.trim().toLowerCase().startsWith('send-tab'); |
| import { isSendTabEntrypoint } from '../../Signin/utils'; | ||
|
|
||
| export const viewName = 'pair.auth.complete'; | ||
|
|
There was a problem hiding this comment.
AuthComplete imports isSendTabEntrypoint from pages/Signin/utils, which brings in a lot of sign-in-specific dependencies that this page doesn’t otherwise need. Consider moving the Send Tab entrypoint predicate into a small shared helper (e.g., near SEND_TAB_ENTRYPOINTS) to avoid coupling Pair pages to the full Signin utils module.
| import { isSendTabEntrypoint } from '../../Signin/utils'; | |
| export const viewName = 'pair.auth.complete'; | |
| export const viewName = 'pair.auth.complete'; | |
| const SEND_TAB_ENTRYPOINTS = new Set<string>(['preferences', 'fxa_pairing']); | |
| const isSendTabEntrypoint = (entrypoint?: string) => | |
| !!entrypoint && SEND_TAB_ENTRYPOINTS.has(entrypoint); |
vpomerleau
left a comment
There was a problem hiding this comment.
Changes look reasonable. One small string suggestion + it looks like a functional test needs to be updated to look for the banner/success message instead of the query params.
| <h1 class="mb-5 text-grey-400 text-base" id="cad-header">{{#t}}Connect another device{{/t}}</h1> | ||
| <h2 id="pair-header" class="card-header focus:outline-none" tabindex="-1">{{#t}}Sync your Firefox experience{{/t}}</h2> | ||
| {{#isSendTab}} | ||
| <h1 id="pair-header" class="card-header focus:outline-none" tabindex="-1">{{#t}}Download or open Firefox on the device where you want to send tabs{{/t}}</h1> |
There was a problem hiding this comment.
Should this be receive instead of send?
| <h1 id="pair-header" class="card-header focus:outline-none" tabindex="-1">{{#t}}Download or open Firefox on the device where you want to send tabs{{/t}}</h1> | |
| <h1 id="pair-header" class="card-header focus:outline-none" tabindex="-1">{{#t}}Download or open Firefox on the device where you want to receive tabs{{/t}}</h1> |
There was a problem hiding this comment.
I ran this by Ross and Laurel - sounds like for now at least we want to leave it since we always talk about "sending" tabs instead of "receiving" them. I suggested "where you want to send your tabs", but this sentence was approved by Content so I'm going to leave it. This is a great flag though!
…ckbone & React Because: * Send Tab entrypoints need a "send some tabs" layout on /pair and /pair/auth/complete * For new send tab entrypoints, always navigate directly to /pair - #20333 added three /pair success banners via query params, but the React conversion only renders one This commit: * getSyncNavigate branches on config.showReactApp.pairRoutes: React soft-navs with locationState.origin; Backbone keeps the hard-nav + query params * Pair/Index renders all three banner variants above the headings; fixes pair-cad-header to "Connect another device" * Adds a Send Tab variant to /pair (both apps) with a single H1 "Download or open Firefox on the device where you want to send tabs" * Adds a Send Tab variant to /pair/auth/complete (both apps) with "You're ready to send some tabs" + dynamic device copy, no CTA * Adds SEND_TAB_ENTRYPOINTS to fxa-content-server constants closes FXA-11984 closes FXA-13414
|
Merging - the only failure is the |
Because:
This commit:
closes FXA-11984
closes FXA-13414
New account on React through Send Tab:
Then the existing account sign-in always skips inline recovery key promo:
