Add August product marketing window - #98565
Conversation
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx ts-node ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
…st-product-marketing-window
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx bun ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
Screenshots and videos look good to me 👍 |
|
Great shout 👍 I like that idea. Would be nice to make a follow-up on that now cause we'll keep updating this each month I assume? |
|
Yup that makes sense. @KJ21-ENG thoughts on the idea before I make an issue? |
|
@shawnborton I loved the idea, as it had seemed off to me since last month when I was working on implementing this marketing window. All this time I had been thinking about how to make it load faster😅, but the spinner now makes more sense to me as well :) |
|
@shawnborton @dubielzyk-expensify Do you need an ad hoc build to test? |
|
Thoughts ? Screen.Recording.2026-08-17.at.10.14.49.AM.compressed.mp4 |
That looks good.
I'll kick one off |
|
🚧 dubielzyk-expensify has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
thanks, @JS00001 all yours |
|
looks like @Julesssss is assigned to this one, lmk if you want a second review! |
|
🚧 Julesssss has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
Sorry, wrong tag 😅 I typed |
|
🚀 Deployed to staging by https://github.com/Julesssss in version: 9.4.57-0 🚀
|
|
🤖 I reviewed the changes in this PR against Expensify's help site files under Why no docs changes are needed: This PR updates the in-app product marketing window — a transient promotional pop-up that replaces the July announcement with the August admin ("Enhanced vendor mapping") and eligible-member ("Pre-built agents for you") variants, refreshes its copy and images, and adds CTA routing/loading logic.
Since the change is limited to the marketing window UI, copy, assets, and CTA routing — and the destination features are already documented — there's nothing to add or update in the help site. @KJ21-ENG, if you believe a specific behavior surfaced here should be reflected in a help article, let me know which one and I'll draft the docs PR. |
|
Deploy Blocker #99027 was identified to be related to this PR. |
Looking into this 👀 |
|
Replied here. |
|
Deploy Blocker #99034 was identified to be related to this PR. |
|
@KJ21-ENG Could you please clarify the steps, what account should we use for this PR ?
|
|
@izarutskaya Point 2 and 6 may help you to understand it. Tell me if they are not helpful, I will explain it |
|
@KJ21-ENG I see this
|
|
According step 8, after creating a new Expensifail account with a QBO-connected workspace, the August product marketing modal did not appear. Could you please take a look at this and let me know? Step.8.fails.mp4Also, how can we check on step 11, if an account dismissed the July campaign modal? Thank you |
@izarutskaya This is expected for this account. The member window appears when the account has Custom Agent beta access and is not an admin of any active workspace. The Agents option visible in your screenshot indicates that the account has the required access, so you can use this account for steps 2–5. |
@izarutskaya Could you confirm whether this account previously dismissed or pressed Try it out on the member window? The member and admin windows belong to the same August campaign, so interacting with either one dismisses the August campaign for that account. Please use a separate fresh admin account for step 8. You can check the campaign dismissal value on staging by running this in DevTools:
For step 11, please use an older account that returns |
|
@KJ21-ENG Issue from step 8 is still reproducible. Also, the modal was not dismissed in the previous testing Repro.-.Step.8.fails.mp4Probably snippet isn’t working. Could you please check and let me know if we doing this correctly? snippet.not.working.mp4 |
|
Thanks, I reviewed both recordings and ran a separate control test on staging. I've attached a recording from a different fresh synthetic admin account. It shows the account selecting QuickBooks Online during onboarding, creating an owned workspace, and then receiving the Enhanced vendor mapping window. On that account, the direct awaited dismissal value was This recording does not reproduce your complete QBO-connected and Vendors-enabled setup, so it does not invalidate your report. It only confirms that the marketing window is not globally missing for every fresh admin account. The reason it remains absent on your specific account is still unresolved. The diagnostic shown in your recording is ambiguous because await window.Onyx.get('nvp_lastDismissedMarketingWindow')Please share the literal result displayed on the next line:
If the value is not const [dismissed, isLoadingApp, isCovered, session, account, modal] = await Promise.all([
window.Onyx.get('nvp_lastDismissedMarketingWindow'),
window.Onyx.get('isLoadingApp'),
window.Onyx.get('isProductMarketingWindowCovered'),
window.Onyx.get('session'),
window.Onyx.get('account'),
window.Onyx.get('modal'),
]);
({
dismissed,
isLoadingApp,
isCovered,
isAnonymous: session?.authTokenType === 'anonymous',
isActingAsDelegate: Boolean(account?.delegatedAccess?.delegate),
needsTwoFactorAuthSetup: account?.needsTwoFactorAuthSetup,
requiresTwoFactorAuth: account?.requiresTwoFactorAuth,
twoFactorAuthSetupInProgress: account?.twoFactorAuthSetupInProgress,
modalVisible: Boolean(modal?.isVisible),
path: location.pathname,
});That result should identify which account-specific visibility gate is suppressing the window. pr-98565-step8-fresh-admin-visibility.mp4 |
|
🚀 Deployed to production by https://github.com/Beamanator in version: 9.4.57-3 🚀
Bundle Size Analysis (Sentry): |



Explanation of Change
Replaces the July product marketing announcement with the August admin and eligible member variants and their supplied images. The admin CTA uses the selected admin workspace's hydrated accounting connections to route to Vendors when enabled, or safely falls back to More Features while offline or after a failed connection refresh. Members with Custom Agent access can open the new Agents flow without bypassing its beta boundary. Dismissal remains campaign-keyed and is persisted before navigation.
Fixed Issues
$ #98233
PROPOSAL: #98233 (comment)
Tests
ProductMarketingWindowappear in the JS console.ProductMarketingWindowappear in the JS consoleOffline tests
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Record_2026-08-16-03-39-38_40d2c9e2d8fb5b5aba3904834590021e.compressed.mp4
Android: mWeb Chrome
Record_2026-08-15-12-10-46.mp4
iOS: Native
Simulator.Screen.Recording.-.iPhone.17.-.2026-08-15.at.17.24.55.compressed.mp4
iOS: mWeb Safari
Simulator.Screen.Recording.-.iPhone.17.-.2026-08-15.at.14.26.29.compressed.mp4
MacOS: Chrome / Safari
Pre-review POC evidence from the earlier candidate. This does not replace final-head, all-platform recordings.
Member marketing window:
Admin marketing window:
More Features fallback:
Direct Vendors destination:
Video:
Screen.Recording.2026-08-13.at.11.43.16.AM.compressed.mp4