fix(docs): re-initialize search after Astro View Transitions#964
fix(docs): re-initialize search after Astro View Transitions#964bradygaster merged 1 commit intodevfrom
Conversation
Wraps DOM lookups and event listeners in initSearch() driven by astro:page-load event. Pagefind instance persists across navigations. Old event listeners torn down before re-attaching. Global keydown listener registered once via guard flag. Adds 2 Playwright regression tests for post-navigation search. Closes #712 Co-authored-by: CarlosSardo <5127825+CarlosSardo@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes the docs site search breaking after Astro View Transitions by re-initializing DOM references and event listeners on astro:page-load, and adds Playwright coverage to prevent regression.
Changes:
- Reworks
Search.astroto re-query DOM elements and re-bind handlers onastro:page-loadafter client-side navigations. - Adds Playwright regression tests ensuring the search modal still works (button + Ctrl+K) after navigating via a search result.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| docs/src/components/Search.astro | Re-initialize search UI DOM references + event handlers after View Transition navigations. |
| docs/tests/search.spec.mjs | Adds/adjusts Playwright coverage for post-navigation search behavior. |
| <span class="hidden sm:inline">Search docs…</span> | ||
| <kbd class="hidden sm:inline-flex ml-auto text-xs border border-surface-300 dark:border-surface-600 rounded px-1.5 py-0.5 text-surface-400" id="search-shortcut-kbd"> | ||
| <span class="text-xs" id="search-modifier">⌘</span>K | ||
| <span class="text-xs" id="search-modifier">Γîÿ</span>K | ||
| </kbd> |
There was a problem hiding this comment.
Several user-visible strings appear to have mojibake/encoding corruption (e.g., "Search docsΓǪ" and the modifier glyph "Γîÿ"). These should be the intended Unicode characters (ellipsis and ⌘) so the UI renders correctly across browsers.
| @@ -39,7 +39,7 @@ | |||
| <div id="search-status" class="hidden px-4 py-2 text-xs text-surface-500 dark:text-surface-400 border-b border-surface-100 dark:border-surface-800"></div> | |||
| <div id="search-results" class="max-h-[60vh] overflow-y-auto p-2"> | |||
| <div class="p-8 text-center text-surface-400 text-sm" id="search-empty"> | |||
| Start typing to search… | |||
| Start typing to search… | |||
| </div> | |||
There was a problem hiding this comment.
The search input placeholder / empty-state text contains mojibake ("…") instead of the intended ellipsis character. This will show incorrect characters in the docs UI; please restore the proper Unicode punctuation.
| function closeSearch() { | ||
| searchModal?.classList.add('hidden'); | ||
| if (searchInput) searchInput.value = ''; | ||
| if (searchResults) searchResults.innerHTML = ''; | ||
| if (searchEmpty) { | ||
| searchResults?.appendChild(searchEmpty); | ||
| searchEmpty.textContent = 'Start typing to search…'; | ||
| searchEmpty.textContent = 'Start typing to search…'; | ||
| } |
There was a problem hiding this comment.
The empty-state reset string in closeSearch() has mojibake ("Start typing to search…"). This should match the actual empty-state copy (using a real ellipsis) to avoid rendering incorrect text and to keep tests/UX consistent.
| async function performSearch() { | ||
| const query = searchInput?.value?.trim(); | ||
| if (!query) { | ||
| if (searchResults && searchEmpty) { | ||
| searchResults.innerHTML = ''; | ||
| searchEmpty.textContent = 'Start typing to search…'; | ||
| searchEmpty.textContent = 'Start typing to search…'; | ||
| searchResults.appendChild(searchEmpty); | ||
| } |
There was a problem hiding this comment.
performSearch() sets the empty-state text to a mojibake string ("Start typing to search…"). Please restore the intended punctuation (ellipsis) so the UI copy is correct.
| } catch { | ||
| if (searchResults) { | ||
| searchResults.innerHTML = '<div class="p-8 text-center text-surface-400 text-sm">Search index loading…</div>'; | ||
| searchResults.innerHTML = '<div class="p-8 text-center text-surface-400 text-sm">Search index loading…</div>'; |
There was a problem hiding this comment.
The fallback HTML for the loading state contains mojibake ("Search index loading…"). This will render incorrectly; please restore the intended ellipsis character.
| searchResults.innerHTML = '<div class="p-8 text-center text-surface-400 text-sm">Search index loading…</div>'; | |
| searchResults.innerHTML = '<div class="p-8 text-center text-surface-400 text-sm">Search index loading…</div>'; |
| // Detect OS and update shortcut badge | ||
| const isMac = /Mac|iPhone|iPad|iPod/.test(navigator.platform); | ||
| const modifierEl = document.getElementById('search-modifier'); | ||
| if (modifierEl) { | ||
| modifierEl.textContent = isMac ? '⌘' : 'Ctrl+'; | ||
| modifierEl.textContent = isMac ? 'Γîÿ' : 'Ctrl+'; | ||
| } |
There was a problem hiding this comment.
The shortcut modifier text for macOS is set to a mojibake glyph ("Γîÿ") instead of "⌘". This will display incorrectly in the keyboard shortcut hint; please restore the correct character.
| test('no results state shows appropriate message', async ({ page }) => { | ||
| await openSearchViaButton(page); | ||
| const input = page.locator('#search-input'); | ||
| // Use a single random character that pagefind won't match | ||
| await input.fill('ÿ'); | ||
| await input.fill('├┐'); | ||
|
|
||
| // Wait for search debounce, then check for either "No results" or | ||
| // the default "Start typing" (pagefind may not index this character). | ||
| // The search executes and either shows "No results for..." or results. | ||
| // We verify the search system responds to input. | ||
| await page.waitForTimeout(1500); | ||
| const resultsContainer = page.locator('#search-results'); | ||
| const text = await resultsContainer.textContent(); | ||
| // Either we get "No results" or actual results — either way the | ||
| // Either we get "No results" or actual results ΓÇö either way the | ||
| // search pipeline processed the query (not still on "Start typing") | ||
| expect(text.trim()).not.toBe('Start typing to search…'); | ||
| expect(text.trim()).not.toBe('Start typing to search…'); |
There was a problem hiding this comment.
This test appears to contain mojibake/encoding corruption (e.g., filling "├┐" and expecting "Start typing to searchΓǪ"). This likely came from mis-decoding UTF-8 ("ÿ", "…", "—"); please restore the intended characters so the test asserts against the real UI copy.
…964) Wraps DOM lookups and event listeners in initSearch() driven by astro:page-load event. Pagefind instance persists across navigations. Old event listeners torn down before re-attaching. Global keydown listener registered once via guard flag. Adds 2 Playwright regression tests for post-navigation search. Closes #712 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: CarlosSardo <5127825+CarlosSardo@users.noreply.github.com>
Rebased cherry-pick of CarlosSardo's fix from PR #713.
Fixes docs search becoming non-functional after navigating via Astro View Transitions. Wraps DOM lookups in initSearch() driven by astro:page-load event.
Closes #712
Original PR: #713 by @CarlosSardo
Co-authored-by: CarlosSardo 5127825+CarlosSardo@users.noreply.github.com