Skip to content

Commit 91d5415

Browse files
committed
improve URL parameter syncing with debouncing in Library component
1 parent e41d2a8 commit 91d5415

2 files changed

Lines changed: 56 additions & 48 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Changes
66

77
- [#6](https://github.com/Phalcode/gamevault-frontend/issues/6) - Use proper href links on game cards and community progress list for better accessibility (middle-click/right-click to open in new tab)
8+
- [#9](https://github.com/Phalcode/gamevault-frontend/issues/9) - Fix search with special characters (apostrophes) causing blank page due to excessive history API calls (added debounce and duplicate URL check)
89

910
## 16.2.0
1011

src/pages/Library.tsx

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -350,68 +350,75 @@ export default function Library() {
350350
urlInitializedRef.current = true;
351351
}, [getParamValues, isBookmark, isEarlyAccess, isGameType, isProgressState]);
352352

353-
// Sync all filters into URL search params for shareable links
353+
// Sync all filters into URL search params for shareable links (debounced)
354354
useEffect(() => {
355355
if (typeof window === "undefined") return;
356356
if (!urlInitializedRef.current) return;
357357

358-
const url = new URL(window.location.href);
359-
const params = url.searchParams;
358+
const timeoutId = setTimeout(() => {
359+
const url = new URL(window.location.href);
360+
const params = url.searchParams;
360361

361-
if (search.trim().length > 0) params.set("q", search.trim());
362-
else params.delete("q");
362+
if (search.trim().length > 0) params.set("q", search.trim());
363+
else params.delete("q");
363364

364-
if (sortBy !== "sort_title") params.set("sort", sortBy);
365-
else params.delete("sort");
365+
if (sortBy !== "sort_title") params.set("sort", sortBy);
366+
else params.delete("sort");
366367

367-
if (order !== "ASC") params.set("order", order);
368-
else params.delete("order");
368+
if (order !== "ASC") params.set("order", order);
369+
else params.delete("order");
369370

370-
if (bookmarkFilter !== "all") params.set("bookmarked", bookmarkFilter);
371-
else params.delete("bookmarked");
371+
if (bookmarkFilter !== "all") params.set("bookmarked", bookmarkFilter);
372+
else params.delete("bookmarked");
372373

373-
setParamValues(
374-
params,
375-
"types",
376-
selectedGameTypes
377-
.map((i) => String(i.id))
378-
.filter((v): v is GamevaultGameTypeEnum => isGameType(v)),
379-
);
380-
setParamValues(
381-
params,
382-
"tags",
383-
selectedTags.map((t) => t.name),
384-
);
385-
setParamValues(
386-
params,
387-
"genres",
388-
selectedGenres.map((g) => g.name),
389-
);
390-
setParamValues(
391-
params,
392-
"developers",
393-
selectedDevelopers.map((d) => d.name),
394-
);
395-
setParamValues(
396-
params,
397-
"publishers",
398-
selectedPublishers.map((p) => p.name),
399-
);
374+
setParamValues(
375+
params,
376+
"types",
377+
selectedGameTypes
378+
.map((i) => String(i.id))
379+
.filter((v): v is GamevaultGameTypeEnum => isGameType(v)),
380+
);
381+
setParamValues(
382+
params,
383+
"tags",
384+
selectedTags.map((t) => t.name),
385+
);
386+
setParamValues(
387+
params,
388+
"genres",
389+
selectedGenres.map((g) => g.name),
390+
);
391+
setParamValues(
392+
params,
393+
"developers",
394+
selectedDevelopers.map((d) => d.name),
395+
);
396+
setParamValues(
397+
params,
398+
"publishers",
399+
selectedPublishers.map((p) => p.name),
400+
);
401+
402+
if (selectedGameState) params.set("state", selectedGameState);
403+
else params.delete("state");
400404

401-
if (selectedGameState) params.set("state", selectedGameState);
402-
else params.delete("state");
405+
if (releaseDateFrom) params.set("releasedAfter", releaseDateFrom);
406+
else params.delete("releasedAfter");
403407

404-
if (releaseDateFrom) params.set("releasedAfter", releaseDateFrom);
405-
else params.delete("releasedAfter");
408+
if (releaseDateTo) params.set("releasedBefore", releaseDateTo);
409+
else params.delete("releasedBefore");
406410

407-
if (releaseDateTo) params.set("releasedBefore", releaseDateTo);
408-
else params.delete("releasedBefore");
411+
if (earlyAccess !== "all") params.set("earlyAccess", earlyAccess);
412+
else params.delete("earlyAccess");
409413

410-
if (earlyAccess !== "all") params.set("earlyAccess", earlyAccess);
411-
else params.delete("earlyAccess");
414+
// Only update URL if it actually changed to avoid rate-limiting errors
415+
const newUrl = url.toString();
416+
if (newUrl !== window.location.href) {
417+
window.history.replaceState({}, "", newUrl);
418+
}
419+
}, 300);
412420

413-
// We intentionally do not push to history each keystroke of search for cleanliness
414-
window.history.replaceState({}, "", url.toString());
421+
return () => clearTimeout(timeoutId);
415422
}, [
416423
bookmarkFilter,
417424
earlyAccess,

0 commit comments

Comments
 (0)