[object Object]

← back to build-pages

search: ?q= deep-link — input hydrates from URL + replaceState keeps URL in sync

9cd86d60cbe2fc04d4e7ac399c4bef2520804251 · 2026-05-13 12:50:47 -0700 · SteveStudio2

Files touched

Diff

commit 9cd86d60cbe2fc04d4e7ac399c4bef2520804251
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 13 12:50:47 2026 -0700

    search: ?q= deep-link — input hydrates from URL + replaceState keeps URL in sync
---
 server.js | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/server.js b/server.js
index 431c688..055e57f 100644
--- a/server.js
+++ b/server.js
@@ -270,7 +270,7 @@ app.get('/p/:slug', async (req, res, next) => {
 
       <section class="bp-section">
         <h2>Search the build</h2>
-        <input id="q" class="bp-q" type="search" placeholder="filter commits by subject, body, file…" autocomplete="off">
+        <input id="q" class="bp-q" type="search" placeholder="filter commits by subject, body, file…" autocomplete="off" value="${esc(typeof req.query.q === 'string' ? req.query.q : '')}">
         <p id="bp-tally" class="bp-meta">${commits.length} commits indexed</p>
         <ol id="bp-commits" class="bp-commits">
           ${commits.map(c => `
@@ -314,17 +314,24 @@ app.get('/p/:slug', async (req, res, next) => {
         const q = document.getElementById('q');
         const list = document.getElementById('bp-commits');
         const tally = document.getElementById('bp-tally');
-        q.addEventListener('input', () => {
+        function applyFilter() {
           const term = q.value.toLowerCase().trim();
           let shown = 0;
           for (const li of list.children) {
-            const blob = li.dataset.blob;
-            const match = !term || blob.includes(term);
+            const match = !term || li.dataset.blob.includes(term);
             li.style.display = match ? '' : 'none';
             if (match) shown++;
           }
           tally.textContent = term ? \`\${shown} / \${DATA.length} match "\${q.value}"\` : \`\${DATA.length} commits indexed\`;
-        });
+          // Reflect search state in URL so a filtered view is shareable. Use
+          // replaceState so the back button still escapes the project page.
+          const url = new URL(window.location.href);
+          if (term) url.searchParams.set('q', q.value); else url.searchParams.delete('q');
+          history.replaceState(null, '', url);
+        }
+        q.addEventListener('input', applyFilter);
+        // Apply the initial ?q= from the server-rendered value field.
+        if (q.value) applyFilter();
       </script>
     `));
   } catch (e) { next(e); }

← 99da4a9 registry: add asseeninmovies + starsofdesign + build-pages (  ·  back to build-pages  ·  smoke: assert /p/:slug?q= hydrates search input on server-re f8e102d →