Approaches to saving search state
History state with a fallback query
const apiUrl =
window.location.hostname === "localhost"
? "http://localhost:8000/query"
: "https://api.zalgorithm.com/query";
function loadKaTexCSS() {
if (document.getElementById("katex-css")) return;
const link = document.createElement("link");
link.id = "katex-css";
link.rel = "stylesheet";
link.href = "https://cdn.jsdelivr.net/npm/katex@0.16.25/dist/katex.min.css";
link.integrity =
"sha384-WcoG4HRXMzYzfCgiyfrySxx90XSl2rxY5mnVY5TwtWE6KLrArNKn0T/mOgNL0Mmi";
link.crossOrigin = "anonymous";
document.head.appendChild(link);
}
function loadSearchResults() {
const urlParams = new URLSearchParams(window.location.search);
const query = urlParams.get("q");
if (query) {
document.getElementById("semantic-search").value = query;
// conditionally load katex-css
// TODO: confirm this and conditional loading in fetch call below
if (history.state && history.state.results) {
if (history.state.results.includes('class="katex"')) {
loadKaTexCSS();
}
document.getElementById("search-results").innerHTML =
history.state.results;
} else {
const formData = new FormData();
formData.append("query", query);
fetch(apiUrl, {
method: "POST",
body: formData,
})
.then((response) => response.text())
.then((html) => {
if (html.includes('class="katex"')) {
loadKaTexCSS();
}
document.getElementById("search-results").innerHTML = html;
history.replaceState(
{ query: query, results: html },
"",
window.location.href,
);
});
}
}
}
document.addEventListener("DOMContentLoaded", loadSearchResults);
// handle back/forward navigation
window.addEventListener("popstate", loadSearchResults);
document.body.addEventListener("htmx:afterRequest", function (evt) {
const form = evt.detail.elt;
if (form.querySelector("#semantic-search")) {
const query = form.querySelector("#semantic-search").value;
if (query && evt.detail.successful) {
const results = document.getElementById("search-results").innerHTML;
history.pushState(
{ query: query, results: results },
"",
"?q=" + encodeURIComponent(query),
);
}
}
});
Session Storage
document.body.addEventListener("htmx:afterRequest", function (evt) {
const form = evt.detail.elt;
if (form.querySelector("#semantic-search")) {
const query = form.querySelector("#semantic-search").value;
if (query && evt.detail.successful) {
const results = document.getElementById("search-results").innerHTML;
// Store in sessionStorage
sessionStorage.setItem(`search_${query}`, results);
// Only store query in history
history.pushState(
{ query: query },
"",
"?q=" + encodeURIComponent(query),
);
}
}
});
function loadSearchResults() {
const urlParams = new URLSearchParams(window.location.search);
const query = urlParams.get("q");
if (query) {
document.getElementById("semantic-search").value = query;
// Try sessionStorage first
const cached = sessionStorage.getItem(`search_${query}`);
if (cached) {
document.getElementById("search-results").innerHTML = cached;
if (cached.includes('class="katex"')) loadKaTexCSS();
} else {
// Fetch fresh...
}
}
}
Tags: