Skip to content

fix: Homepage product navigation#4949

Open
prajwalnl wants to merge 3 commits into
mainfrom
fix/homepage-product-navigation
Open

fix: Homepage product navigation#4949
prajwalnl wants to merge 3 commits into
mainfrom
fix/homepage-product-navigation

Conversation

@prajwalnl

@prajwalnl prajwalnl commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

Fixes broken navigation from the homepage ("Explore composable services" cards). Clicking a product's Learn More button now consistently opens the merchant-switch modal, switches into the selected product, and lands the user on that product's home page.

Changes:

  • DefaultHomeUtils.res — DefaultHomeCard now always routes an InternalRoute click through onProductSelectClick(heading), removing the previous if product === activeProduct { …direct navigate… } else { …modal… } split. The unused ~product prop, activeProduct, and isLiveMode bindings were dropped from the component.
  • DefaultHome.res — removed the now-unused product=item.product prop from all five DefaultHomeCard usages.
  • ProductSelectionProviderHelper.res — after internalSwitch completes, each of the three modal bodies (SwitchMerchantBody, SelectMerchantBody, CreateNewMerchantBody) now restores the active product and navigates to the product home:
    setActiveProductValue(selectedProduct)
    let productUrl = ProductUtils.getProductUrl(~productType=selectedProduct, ~isLiveMode)
    RescriptReactRouter.replace(productUrl)
  • (isLiveMode is read in each body because getProductUrl needs it for the Recovery live/test route.)

Same product switch

Screen.Recording.2026-06-09.at.3.53.24.PM.mov

Switch between products

Screen.Recording.2026-06-09.at.3.54.22.PM.mov

Switch when single merchant present for a product

Screen.Recording.2026-06-09.at.3.55.03.PM.mov

Motivation and Context

Selecting a product from the homepage was either bouncing back to /v2/home or behaving differently per product. Two root causes:

  1. Inconsistent equality check. The card used physical equality (===) to decide whether to navigate directly or open the switch modal. ProductTypes.productTypes mixes nullary constructors (Vault, Recovery, CostObservability → compiled to integers, where === works) with payload-carrying ones (Orchestration(V1), Recon(V2) → compiled to objects, where === is always false). As a result only Orchestrator/Recon reliably opened the modal, while the others took the direct-navigate path — producing the inconsistent behavior. Routing every click through onProductSelectClick makes all products behave the same.
  2. activeProduct not restored on a no-op switch. onProductSelectClick sets activeProduct = UnknownProduct as a loading state, and it was only restored by setUpDashboard in HyperSwitchApp.res, whose effect is keyed on [orgId, merchantId, profileId]. When the user selects the product they're already in, internalSwitch is a no-op (same merchant), so the effect never re-runs and activeProduct stays UnknownProduct → the router renders (UnknownProduct, _) => React.null (blank page). Explicitly calling setActiveProductValue(selectedProduct) in the modal restores it in both the changed-merchant and no-op cases, and the added replace(productUrl) performs the actual navigation to the product home.

Resolves #3460.

How did you test it?

Where to test it?

  • INTEG
  • SANDBOX
  • PROD

Backend Dependency

  • Yes
  • No

Backend PR URL:

Feature Flag

  • New feature flag added
  • Existing feature flag updated
  • No feature flag changes

Feature flag name(s):

Checklist

  • I ran npm run re:build
  • I reviewed submitted code
  • I added unit tests for my changes where possible

@prajwalnl prajwalnl requested a review from a team as a code owner June 9, 2026 10:39
@semanticdiff-com

Copy link
Copy Markdown

Review changes with  SemanticDiff

@prajwalnl prajwalnl self-assigned this Jun 9, 2026
@prajwalnl

Copy link
Copy Markdown
Contributor Author

@control_center_review_bot please review this pr

@prajwalnl

Copy link
Copy Markdown
Contributor Author

@XyneSpaces please review this pr

@github-actions github-actions Bot added the R-ready-for-review PR is ready for reviewing label Jun 9, 2026

@XyneSpaces XyneSpaces 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.

Automated Review Summary

PR: fix: Homepage product navigation
Reviewer: XyneSpaces Automation

Findings

Found 1 issue requiring attention:

⚠️ Error handling in async switch operations could leave UI in inconsistent state

The catch block in all three modal bodies (SwitchMerchantBody, SelectMerchantBody, CreateNewMerchantBody) only shows a toast on failure but doesn't prevent the subsequent navigation logic from executing. If internalSwitch fails, the code still calls setActiveProductValue and RescriptReactRouter.replace, potentially navigating to a product page that hasn't actually been switched to.

Fix: Move the navigation logic (setActiveProductValue and replace) inside the try block, after the internalSwitch call succeeds, or add an early return in the catch block.


Verdict: Address the error handling issue before merge.

let _ = await internalSwitch(~expectedMerchantId=Some(merchantDetails.id), ~version)
setActiveProductValue(selectedProduct)
let productUrl = ProductUtils.getProductUrl(~productType=selectedProduct, ~isLiveMode)
RescriptReactRouter.replace(productUrl)

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.

⚠️ Navigation executes even if internalSwitch fails. Move setActiveProductValue and RescriptReactRouter.replace inside the try block after internalSwitch succeeds, or add early return in catch.

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

Labels

R-ready-for-review PR is ready for reviewing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Broken navigation to product from Homepage

2 participants