Design Doc
https://docs.google.com/document/d/1rqbBWVJoOtyptW6IcyzodKq-1l8e9qXVYDm2_6Raots/edit?tab=t.0
Proposal
Made by Yehor (@collectioneur) in https://expensify.slack.com/archives/C08CZDJFJ77/p1758798849102299
Background:
Right now, our navigation system relies on special URL parameters called backTo and forwardTo. These parameters are used when a user opens a screen that is reused in multiple different flows (for instance, the VerifyAccountPage is used in both settings/wallet and workspaces/:policyID/invoices.). Their purpose is to make sure that, if the page is refreshed or opened from a link, the app knows where to send the user back to or forward to.
The downside is that these parameters make our URLs long and messy. Because of this, we’re currently running a large refactor to remove them from the URL. The current approach is to replace them by adding separate routes for every flow that uses such a screen, usually one or two routes at a time. By the time this refactor is done, we’ll end up with 240 new routes. With static URLs, adding just one route typically means touching at least seven files (often more) and configuring all required parameters.
Problem:
The issue with this approach is scale. For every flow and every screen that currently depends on backTo or forwardTo, we need to create a dedicated route. On top of that, we often need to configure extra path parameters (like reportId or policyId) so that no information is lost. These routes will clutter navigation files, make them harder to maintain, and add a lot of weight to the code - all for the single purpose of removing backTo and forwardTo.
Solution:
Instead of creating static routes, we can introduce a dynamic URL modification system. This system would update the path directly by appending a short suffix to the URL (different for each component that previously relied on backTo). All other parameters would remain intact.
(Using the same example, it would work like this:
settings/wallet -> settings/wallet/verify-account
workspaces/12345/invoices -> workspaces/12345/invoices/verify-account)
This means we can always reconstruct the “back” path simply by trimming off the suffix, while keeping the URL short, clean, and user-friendly. Most importantly, we would not need to create any additional routes or components at all — they would be handled dynamically.
With static routes, we have to mount the same component separately for each static route. With the dynamic approach, it's mounted only once and then reused.
This approach greatly reduces the amount of code, speeds up the refactor, and keeps navigation files lean.
A working example of this solution is already implemented in this PR for the VerifyAccount screen.
In the thread, I’ve attached a comparison showing what a dynamic URL looks like versus what we have now.
Tasks
Design Doc
https://docs.google.com/document/d/1rqbBWVJoOtyptW6IcyzodKq-1l8e9qXVYDm2_6Raots/edit?tab=t.0
Proposal
Made by Yehor (@collectioneur) in https://expensify.slack.com/archives/C08CZDJFJ77/p1758798849102299
Background:
Right now, our navigation system relies on special URL parameters called
backToandforwardTo. These parameters are used when a user opens a screen that is reused in multiple different flows (for instance, the VerifyAccountPage is used in bothsettings/walletandworkspaces/:policyID/invoices.). Their purpose is to make sure that, if the page is refreshed or opened from a link, the app knows where to send the user back to or forward to.The downside is that these parameters make our URLs long and messy. Because of this, we’re currently running a large refactor to remove them from the URL. The current approach is to replace them by adding separate routes for every flow that uses such a screen, usually one or two routes at a time. By the time this refactor is done, we’ll end up with 240 new routes. With static URLs, adding just one route typically means touching at least seven files (often more) and configuring all required parameters.
Problem:
The issue with this approach is scale. For every flow and every screen that currently depends on
backToorforwardTo, we need to create a dedicated route. On top of that, we often need to configure extra path parameters (likereportIdorpolicyId) so that no information is lost. These routes will clutter navigation files, make them harder to maintain, and add a lot of weight to the code - all for the single purpose of removingbackToandforwardTo.Solution:
Instead of creating static routes, we can introduce a dynamic URL modification system. This system would update the path directly by appending a short suffix to the URL (different for each component that previously relied on
backTo). All other parameters would remain intact.(Using the same example, it would work like this:
settings/wallet->settings/wallet/verify-accountworkspaces/12345/invoices->workspaces/12345/invoices/verify-account)This means we can always reconstruct the “back” path simply by trimming off the suffix, while keeping the URL short, clean, and user-friendly. Most importantly, we would not need to create any additional routes or components at all — they would be handled dynamically.
With static routes, we have to mount the same component separately for each static route. With the dynamic approach, it's mounted only once and then reused.
This approach greatly reduces the amount of code, speeds up the refactor, and keeps navigation files lean.
A working example of this solution is already implemented in this PR for the VerifyAccount screen.
In the thread, I’ve attached a comparison showing what a dynamic URL looks like versus what we have now.
Tasks
#expensify-open-sourcestrategy@expensify.comand paste in the Proposalstrategy@expensify.com(continue the same email chain as before) with the link to your Design Doc#expensify-open-sourceto discuss any necessary details in public before filling out the High-level of proposed solution section.stategy@expensify.comagain with links to the doc and pre-design conversation in SlackDesignDocReviewlabel to get the High-level of proposed solution section reviewed#expensify-open-sourceto ask for engineering feedback on the technical solution.DesignDocReviewlabel to this issuestrategy@expensify.comone last time to let them know the Design Doc is moving into the implementation phasestrategy@expensify.comonce everything has been implemented and do a Project Wrap-Up retrospective that provides: