Skip to content

feat: preserve search query when modal closes and reopens #5167

Open
Madhubytee wants to merge 1 commit intoasyncapi:masterfrom
Madhubytee:feat/preserve-search-query
Open

feat: preserve search query when modal closes and reopens #5167
Madhubytee wants to merge 1 commit intoasyncapi:masterfrom
Madhubytee:feat/preserve-search-query

Conversation

@Madhubytee
Copy link

@Madhubytee Madhubytee commented Feb 16, 2026

Description
Added query persistence to the search modal. Query now stays when you close and reopen the modal instead of getting cleared.

Changes:

  • Preserve search query when the Algolia search modal closes and reopens
  • Read the input value from the DOM on modal close and store it in parent state
  • Query resets on page reload, persists within the same session

Related issue
Resolves #5165

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where search queries were lost when closing the search modal or navigating away from results. User input now persists across modal interactions, improving the search experience and maintaining search context throughout browsing sessions.

@netlify
Copy link

netlify bot commented Feb 16, 2026

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit fe12d3e
🔍 Latest deploy log https://app.netlify.com/projects/asyncapi-website/deploys/6993a860420698000841e3ff
😎 Deploy Preview https://deploy-preview-5167--asyncapi-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

The pull request adds query persistence functionality to the Algolia search modal in AlgoliaSearch.tsx. It introduces an onQueryChange callback prop to the AlgoliaModalProps interface, threads it through the AlgoliaModal component, and implements a handleClose helper that captures the current search input value before closing or navigating, enabling the search query to be preserved across modal open/close cycles.

Changes

Cohort / File(s) Summary
Search Query Persistence
components/AlgoliaSearch.tsx
Added onQueryChange callback to AlgoliaModalProps interface. Updated AlgoliaModal function signature to accept the new prop. Implemented handleClose helper that reads the DocSearch input value and propagates it via onQueryChange before closing. Modified component rendering to pass onQueryChange={setInitialQuery} and use handleClose in close and navigation flows.

Sequence Diagram

sequenceDiagram
    participant User
    participant AlgoliaSearch as AlgoliaSearch<br/>(Parent)
    participant AlgoliaModal as AlgoliaModal<br/>(Modal)
    participant DocSearch as DocSearch<br/>(Input)

    User->>AlgoliaSearch: Opens search modal
    AlgoliaSearch->>AlgoliaModal: Render with onQueryChange callback
    User->>DocSearch: Types search query
    DocSearch->>AlgoliaModal: Input updated
    User->>AlgoliaModal: Closes modal (ESC/click outside)
    AlgoliaModal->>DocSearch: handleClose reads input value
    DocSearch-->>AlgoliaModal: Returns current query text
    AlgoliaModal->>AlgoliaSearch: onQueryChange(query) propagates
    AlgoliaSearch->>AlgoliaSearch: setInitialQuery updates state
    AlgoliaSearch->>AlgoliaModal: Modal unmounts
    User->>AlgoliaSearch: Reopens search modal
    AlgoliaSearch->>AlgoliaModal: Render with preserved initialQuery
    AlgoliaModal->>DocSearch: Input seeded with saved query
    User->>User: Continues typing without retyping
Loading

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A modal that remembers, oh what a delight,
No more lost queries vanishing into the night!
The rabbit hopped closer to search with such glee,
Your words now persist, as they always should be. ✨🔍

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: preserving the search query when the modal closes and reopens, which directly matches the primary objective of the changeset.
Linked Issues check ✅ Passed The implementation meets the core requirements: query is preserved via onQueryChange prop, persists across open/close cycles on the same page, and no breaking changes are introduced.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing query persistence: adding onQueryChange prop, threading it through AlgoliaModal, and updating the handleClose flow to capture the query state.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

@Madhubytee Madhubytee changed the title feat: preserve search query when modal closes and reopens #5165 feat: preserve search query when modal closes and reopens Feb 16, 2026
@sonarqubecloud
Copy link

@SHUBHANSHU602
Copy link

SHUBHANSHU602 commented Feb 16, 2026

@Madhubytee please read the community guidelines , in asyncAPI we wait for maintainer to approve then PR is raised , Please close the PR.

@codecov
Copy link

codecov bot commented Feb 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (c02a12f) to head (fe12d3e).

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #5167   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           22        22           
  Lines          796       796           
  Branches       146       146           
=========================================
  Hits           796       796           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@asyncapi-bot
Copy link
Contributor

⚡️ Lighthouse report for the changes in this PR:

Category Score
🔴 Performance 37
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-5167--asyncapi-website.netlify.app/

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.


In `@components/AlgoliaSearch.tsx`:
- Around line 117-127: The handleClose callback currently gates calling
onQueryChange behind a truthy check of input.value, so empty string clears are
skipped; update handleClose (the function using
document.querySelector('.DocSearch-Input')) to only check that the input element
exists (not its value) and always call onQueryChange(input.value) before
invoking onClose(event) so an empty string correctly clears the persisted query.
- Around line 141-145: The search query persists after navigation because
handleClose calls onQueryChange(input.value) before router.push; fix by clearing
the saved query on route change: inside AlgoliaSearch add a useEffect that
watches router.asPath and calls onQueryChange('') (or otherwise resets
initialQuery) when it changes so the modal opens empty on the new page;
alternatively, remove the onQueryChange call from the navigator.navigate
implementation (the block invoking handleClose and router.push) if you prefer
not to reset on route change. Ensure you reference the existing functions/props:
AlgoliaSearch, handleClose, navigator.navigate, onQueryChange, initialQuery, and
router.asPath.

Comment on lines +117 to +127
const handleClose = useCallback(
(event?: React.MouseEvent) => {
const input = document.querySelector('.DocSearch-Input') as HTMLInputElement;

if (input?.value) {
onQueryChange(input.value);
}
onClose(event);
},
[onClose, onQueryChange]
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Bug: Clearing the search input does not reset the persisted query.

The condition if (input?.value) on line 121 is falsy for an empty string, so onQueryChange is never called when the user deletes all text before closing the modal. On the next open, the stale query reappears — contradicting the PR objective that "query clears if the user manually deletes all text in the input."

Change the guard to only check whether the element was found, not whether its value is truthy:

🐛 Proposed fix
   const handleClose = useCallback(
     (event?: React.MouseEvent) => {
       const input = document.querySelector('.DocSearch-Input') as HTMLInputElement;

-      if (input?.value) {
+      if (input) {
         onQueryChange(input.value);
       }
       onClose(event);
     },
     [onClose, onQueryChange]
   );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleClose = useCallback(
(event?: React.MouseEvent) => {
const input = document.querySelector('.DocSearch-Input') as HTMLInputElement;
if (input?.value) {
onQueryChange(input.value);
}
onClose(event);
},
[onClose, onQueryChange]
);
const handleClose = useCallback(
(event?: React.MouseEvent) => {
const input = document.querySelector('.DocSearch-Input') as HTMLInputElement;
if (input) {
onQueryChange(input.value);
}
onClose(event);
},
[onClose, onQueryChange]
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/AlgoliaSearch.tsx` around lines 117 - 127, The handleClose
callback currently gates calling onQueryChange behind a truthy check of
input.value, so empty string clears are skipped; update handleClose (the
function using document.querySelector('.DocSearch-Input')) to only check that
the input element exists (not its value) and always call
onQueryChange(input.value) before invoking onClose(event) so an empty string
correctly clears the persisted query.

Comment on lines 141 to 145
navigator={{
navigate({ itemUrl }) {
onClose();
handleClose();
router.push(itemUrl);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find where AlgoliaSearch is mounted in the app
rg -n "AlgoliaSearch" -g '*.tsx' -g '*.jsx' -A 3 -B 3

Repository: asyncapi/website

Length of output: 5533


🏁 Script executed:

# Check the AlgoliaSearch component implementation, especially handleClose and state management
rg -n "handleClose|initialQuery|useEffect" components/AlgoliaSearch.tsx -A 2

Repository: asyncapi/website

Length of output: 1392


🏁 Script executed:

# Check if there's any route-change listener in AlgoliaSearch
rg -n "router\.(asPath|pathname|events)" components/AlgoliaSearch.tsx -A 3

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Get the full handleClose implementation
sed -n '117,130p' components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 392


🏁 Script executed:

# Get the useEffect hooks to see dependencies
sed -n '202,220p' components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 837


🏁 Script executed:

# Also check the second useEffect
sed -n '309,325p' components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 661


🏁 Script executed:

# Check onQueryChange implementation and how initialQuery is used
sed -n '247,295p' components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 1316


🏁 Script executed:

# Look for where initialQuery state is actually used and modified
rg -n "setInitialQuery|initialQuery" components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 455


🏁 Script executed:

# Check if there's any route-change handling in the component
grep -n "useRouter\|router\." components/AlgoliaSearch.tsx | head -20

Repository: asyncapi/website

Length of output: 172


🏁 Script executed:

# Get the complete first useEffect with all dependencies
sed -n '202,235p' components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 1253


🏁 Script executed:

# Get the complete second useEffect with all dependencies
sed -n '309,330p' components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 778


🏁 Script executed:

# Check if initialQuery is ever reset/cleared to undefined
rg -n "initialQuery.*undefined|setInitialQuery.*undefined" components/AlgoliaSearch.tsx

Repository: asyncapi/website

Length of output: 42


Query persists across route changes, contradicting stated PR objective.

When a user clicks a search result, handleClose() saves the current search query via onQueryChange(input.value) (line 119) before router.push(itemUrl) navigates away (line 144). Since AlgoliaSearch is mounted at the app level (pages/_app.tsx), it persists across client-side navigations and its state—including initialQuery—survives the route change. No route-change listener clears initialQuery on navigation, so the saved query remains and reappears on the next page when the search modal is opened again.

To align with the stated behavior, either (a) remove the onQueryChange call from the navigator's navigate function, or (b) add a useEffect that clears initialQuery when router.asPath changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/AlgoliaSearch.tsx` around lines 141 - 145, The search query
persists after navigation because handleClose calls onQueryChange(input.value)
before router.push; fix by clearing the saved query on route change: inside
AlgoliaSearch add a useEffect that watches router.asPath and calls
onQueryChange('') (or otherwise resets initialQuery) when it changes so the
modal opens empty on the new page; alternatively, remove the onQueryChange call
from the navigator.navigate implementation (the block invoking handleClose and
router.push) if you prefer not to reset on route change. Ensure you reference
the existing functions/props: AlgoliaSearch, handleClose, navigator.navigate,
onQueryChange, initialQuery, and router.asPath.

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

Labels

None yet

Projects

Status: To Be Triaged

Development

Successfully merging this pull request may close these issues.

3 participants

Comments