Skip to content

deal with browser back button - #271

Merged
bordalix merged 4 commits into
masterfrom
back_button
Dec 16, 2025
Merged

bordalix merged 4 commits into
masterfrom
back_button

Conversation

@bordalix

@bordalix bordalix commented Dec 12, 2025 •

Copy link
Copy Markdown
Collaborator

Clicking back on the browser navigates inside the app.

@tiero please review

@theDavidCoen please test

Closes #255

Summary by CodeRabbit

  • New Features

    • Improved navigation history: the app now tracks page history so back/forward actions restore the previous screen and tab.
    • Browser back/forward support: using browser controls will navigate within the app as expected and stay in sync with the UI.
  • Bug Fixes

    • Prevents unwanted back-navigation into initial connection or loading screens; handles edge cases gracefully.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 12, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

Replaced direct navigate state updates with a browser-backed navigation stack (useRef). Added push/pop helpers, history.pushState usage, and a popstate listener to synchronize browser back/forward with in-app screen/tab state while avoiding forbidden pages (e.g., InitConnect/Loading).

Changes

Cohort / File(s) Change Summary
Navigation history & back handling
src/providers/navigation.tsx
Replaced direct navigate state updates with a useRef navigation stack, introduced push(page), pop(), and addEntryToBrowserHistory(), call history.pushState() when available, wired window.popstate handling in useEffect, and updated navigate(page) to delegate to push(page) and set screen/tab from resolved page.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Browser as Browser (window)
participant NavProv as NavigationProvider
participant App as App (screen/tab state)
Note over NavProv,App: User-triggered navigation
Browser->>NavProv: user clicks link / app calls navigate(page)
NavProv->>NavProv: push(page) — update internal stack, history.pushState()
NavProv->>App: set screen/tab to page
Note over Browser,NavProv: Browser back/forward interaction
Browser->>NavProv: popstate event
NavProv->>NavProv: pop() — pop stack, skip forbidden pages
NavProv->>App: set screen/tab to previous page

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to inspect closely:
    • useRef history initialization and mutation semantics
    • pop() edge cases (skipping InitConnect/Loading, empty-history behavior)
    • Ordering between history.pushState() and in-app state updates
    • window.popstate subscription, debouncing/guards, and cleanup in useEffect

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'deal with browser back button' clearly summarizes the main change—addressing browser back button navigation, which is the core objective of this pull request.
Linked Issues check ✅ Passed The changes implement history-based navigation with popstate handling to enable backward navigation within the app instead of exiting, directly addressing issue #255's requirement.
Out of Scope Changes check ✅ Passed All changes in src/providers/navigation.tsx are focused on implementing browser back button support through history management, with no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch back_button

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d17b691 and 5122883.

📒 Files selected for processing (1)
  • src/providers/navigation.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-21T18:25:36.391Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 121
File: src/screens/Init/Restore.tsx:58-58
Timestamp: 2025-07-21T18:25:36.391Z
Learning: In src/screens/Init/Restore.tsx, the Input component for private key restoration intentionally omits the `value` prop to make it uncontrolled. This is a security feature to prevent the private key from being displayed if users navigate away and return to the screen, avoiding potential exposure of sensitive data in the UI.

Applied to files:

  • src/providers/navigation.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 47842f3 and f13c465.

📒 Files selected for processing (1)
  • src/providers/navigation.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-21T18:25:36.391Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 121
File: src/screens/Init/Restore.tsx:58-58
Timestamp: 2025-07-21T18:25:36.391Z
Learning: In src/screens/Init/Restore.tsx, the Input component for private key restoration intentionally omits the `value` prop to make it uncontrolled. This is a security feature to prevent the private key from being displayed if users navigate away and return to the screen, avoiding potential exposure of sensitive data in the UI.

Applied to files:

  • src/providers/navigation.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages: wallet-mutinynet
🔇 Additional comments (4)
src/providers/navigation.tsx (4)

1-1: LGTM!

The additional imports (useEffect and useRef) are necessary for the browser history navigation feature.


181-184: Verify browser history behavior.

The history check on line 182 is redundant in browser environments (history is always defined). More importantly, every call to navigate pushes a new browser history entry. After navigating through multiple pages and clicking back through all of them, one additional back click will exit the app entirely.

Consider using history.replaceState for the first navigation to prevent exiting the app after navigating backward through all pages:

 const push = (page: Pages) => {
-  if (history) history.pushState({}, '', '')
+  if (typeof window !== 'undefined' && window.history) {
+    window.history.pushState({}, '', '')
+  }
   navigationHistory.current.push(page)
 }

Alternatively, to fully prevent exiting the app via back button, consider pushing an initial dummy state on mount and using replaceState for the first navigation.


186-192: LGTM!

The pop function correctly retrieves the previous page from the history stack and defaults to Pages.Init when the stack is empty.


198-202: LGTM!

The navigate function correctly integrates with the new history mechanism by calling push before updating the screen and tab state.

Comment thread src/providers/navigation.tsx Resolved
Comment thread src/providers/navigation.tsx Resolved
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Dec 12, 2025 •

Copy link
Copy Markdown

Deploying wallet-mutinynet with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5122883
Status: ✅  Deploy successful!
Preview URL: https://54cf1fe5.arkade-wallet.pages.dev
Branch Preview URL: https://back-button.arkade-wallet.pages.dev

View logs

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Dec 12, 2025 •

Copy link
Copy Markdown

Deploying wallet-bitcoin with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5122883
Status: ✅  Deploy successful!
Preview URL: https://5614af78.wallet-bitcoin.pages.dev
Branch Preview URL: https://back-button.wallet-bitcoin.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/providers/navigation.tsx (2)

181-184: Consider preventing duplicate consecutive history entries.

The push function always adds the page to the history stack, even if it's already the current page. This creates duplicate entries (e.g., [Init, A, A]) that affect back button behavior—users would need to click back multiple times to navigate away from the same page.

Apply this diff to skip pushing duplicate consecutive entries:

 const push = (page: Pages) => {
+  const lastPage = navigationHistory.current[navigationHistory.current.length - 1]
+  if (lastPage === page) return
   if (history) history.pushState({}, '', '')
   navigationHistory.current.push(page)
 }

Also applies to: 202-206


182-182: Use more defensive check for history object.

The if (history) check works but could be more defensive and consistent with the window check on line 196.

Apply this diff for better defensive coding:

-  if (history) history.pushState({}, '', '')
+  if (typeof window !== 'undefined' && window.history) {
+    window.history.pushState({}, '', '')
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f13c465 and e0abcac.

📒 Files selected for processing (1)
  • src/providers/navigation.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-21T18:25:36.391Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 121
File: src/screens/Init/Restore.tsx:58-58
Timestamp: 2025-07-21T18:25:36.391Z
Learning: In src/screens/Init/Restore.tsx, the Input component for private key restoration intentionally omits the `value` prop to make it uncontrolled. This is a security feature to prevent the private key from being displayed if users navigate away and return to the screen, avoiding potential exposure of sensitive data in the UI.

Applied to files:

  • src/providers/navigation.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages: wallet-mutinynet

Comment thread src/providers/navigation.tsx Resolved

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/providers/navigation.tsx (1)

179-184: Consider consistent SSR guard pattern.

Line 182 uses if (history) while line 202 uses typeof window !== 'undefined'. Both work, but the latter is more defensive in SSR environments where accessing undeclared globals may throw in certain bundler configurations.

 const push = (page: Pages) => {
-  if (history) history.pushState({}, '', '')
+  if (typeof window !== 'undefined') window.history.pushState({}, '', '')
   navigationHistory.current.push(page)
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0abcac and d17b691.

📒 Files selected for processing (1)
  • src/providers/navigation.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-21T18:25:36.391Z
Learnt from: bordalix
Repo: arkade-os/wallet PR: 121
File: src/screens/Init/Restore.tsx:58-58
Timestamp: 2025-07-21T18:25:36.391Z
Learning: In src/screens/Init/Restore.tsx, the Input component for private key restoration intentionally omits the `value` prop to make it uncontrolled. This is a security feature to prevent the private key from being displayed if users navigate away and return to the screen, avoiding potential exposure of sensitive data in the UI.

Applied to files:

  • src/providers/navigation.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages: wallet-mutinynet
🔇 Additional comments (3)
src/providers/navigation.tsx (3)

1-1: LGTM!

Import additions correctly support the new navigation history implementation.


186-198: LGTM!

The pop function correctly addresses all previous review concerns:

  • Wrapped in useCallback with appropriate empty dependency array
  • Guards against emptying the history stack
  • Prevents back navigation to InitConnect
  • State updates are properly sequenced

200-212: LGTM!

  • The useEffect properly cleans up the popstate listener, fixing the previous memory leak concern
  • The dependency array correctly includes pop
  • The navigate function properly sequences history push before state updates

@bordalix
bordalix merged commit 00749d7 into master Dec 16, 2025
5 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Dec 22, 2025
@bordalix
bordalix deleted the back_button branch March 4, 2026 10:13
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.

Clicking the back button in the browser exits the app

2 participants