Skip to content

feat(pair): Send Tab variant and origin-driven messaging on /pair, Backbone & React#20403

Merged
LZoog merged 1 commit intomainfrom
FXA-13414
Apr 21, 2026
Merged

feat(pair): Send Tab variant and origin-driven messaging on /pair, Backbone & React#20403
LZoog merged 1 commit intomainfrom
FXA-13414

Conversation

@LZoog
Copy link
Copy Markdown
Contributor

@LZoog LZoog commented Apr 17, 2026

Because:

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


New account on React through Send Tab:

image

Then the existing account sign-in always skips inline recovery key promo:
image

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 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 /pair with location.state.origin, while keeping Backbone /pair on hard-nav + query params.
  • Implement Send Tab variants for /pair and /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.

Comment thread packages/fxa-settings/src/models/mocks.tsx
Comment thread packages/fxa-settings/src/pages/Signin/utils.ts Outdated
Comment on lines +25 to +29
import { isSendTabEntrypoint } from '../../Signin/utils';
import type { PairOrigin } from '../../Signin/utils';
import type { SigninLocationState } from '../../Signin/interfaces';
import type { Integration } from '../../../models';

Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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');

Copilot uses AI. Check for mistakes.
Comment on lines 18 to 21
import { isSendTabEntrypoint } from '../../Signin/utils';

export const viewName = 'pair.auth.complete';

Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@vpomerleau vpomerleau left a comment

Choose a reason for hiding this comment

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

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>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this be receive instead of send?

Suggested change
<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>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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!

@LZoog LZoog marked this pull request as ready for review April 21, 2026 15:19
@LZoog LZoog requested review from a team as code owners April 21, 2026 15:19
…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
@LZoog
Copy link
Copy Markdown
Contributor Author

LZoog commented Apr 21, 2026

Merging - the only failure is the String extraction test that has a known failure (adding l10n reviewer).

@LZoog LZoog merged commit 83e352f into main Apr 21, 2026
21 of 22 checks passed
@LZoog LZoog deleted the FXA-13414 branch April 21, 2026 16:32
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.

4 participants