diff --git a/packages/wouter/src/memory-location.js b/packages/wouter/src/memory-location.js
index 8e212ef..d018ac4 100644
--- a/packages/wouter/src/memory-location.js
+++ b/packages/wouter/src/memory-location.js
@@ -7,10 +7,12 @@ import { useSyncExternalStore } from "./react-deps.js";
export const memoryLocation = ({
path = "/",
+ searchPath = "",
static: staticLocation,
record,
} = {}) => {
- let currentPath = path;
+ let currentPath = path + (searchPath && (path.split("?")[1] ? "&" : "?")) + searchPath;
+ let currentSearch = currentPath.split("?")[1] || "";
const history = [currentPath];
const emitter = mitt();
@@ -24,6 +26,7 @@ export const memoryLocation = ({
}
currentPath = path;
+ currentSearch = path.split("?")[1] || "";
emitter.emit("navigate", path);
};
@@ -39,15 +42,20 @@ export const memoryLocation = ({
navigate,
];
+ const useMemoryQuery = () => [
+ useSyncExternalStore(subscribe, () => currentSearch)
+ ];
+
function reset() {
// clean history array with mutation to preserve link
history.splice(0, history.length);
- navigateImplementation(path);
+ navigateImplementation(path + (searchPath && (path.split("?")[1] ? "&" : "?")) + searchPath);
}
return {
hook: useMemoryLocation,
+ searchHook: useMemoryQuery,
navigate,
history: record ? history : undefined,
reset: record ? reset : undefined,
diff --git a/packages/wouter/test/memory-location.test.ts b/packages/wouter/test/memory-location.test.ts
index 5b20a99..7ae3c00 100644
--- a/packages/wouter/test/memory-location.test.ts
+++ b/packages/wouter/test/memory-location.test.ts
@@ -23,6 +23,17 @@ it("should support initial path", () => {
unmount();
});
+it("should support initial path with query", () => {
+ const { searchHook } = memoryLocation({ path: "/test-case?foo=bar" });
+ // const { searchHook } = memoryLocation({ path: "/test-case", searchPath: "foo=bar" });
+
+ const { result, unmount } = renderHook(() => searchHook());
+ const [value] = result.current;
+
+ expect(value).toBe("foo=bar");
+ unmount();
+});
+
it('should return location hook that has initial path "/" by default', () => {
const { hook } = memoryLocation();
@@ -33,6 +44,16 @@ it('should return location hook that has initial path "/" by default', () => {
unmount();
});
+it('should return search hook that has initial query "" by default', () => {
+ const { searchHook } = memoryLocation();
+
+ const { result, unmount } = renderHook(() => searchHook());
+ const [value] = result.current;
+
+ expect(value).toBe("");
+ unmount();
+});
+
it("should return standalone `navigate` method", () => {
const { hook, navigate } = memoryLocation();
diff --git a/packages/wouter/test/use-search.test.tsx b/packages/wouter/test/use-search.test.tsx
index ad8fe4d..43e7823 100644
--- a/packages/wouter/test/use-search.test.tsx
+++ b/packages/wouter/test/use-search.test.tsx
@@ -1,6 +1,7 @@
import { renderHook, act } from "@testing-library/react";
import { useSearch, Router } from "wouter";
import { navigate } from "wouter/use-browser-location";
+import { memoryLocation } from "wouter/memory-location";
import { it, expect, beforeEach } from "vitest";
beforeEach(() => history.replaceState(null, "", "/"));
@@ -24,6 +25,18 @@ it("can be customized in the Router", () => {
expect(result.current).toEqual("none");
});
+it("can be customized with memoryLocation", () => {
+ const { searchHook } = memoryLocation({ path: "/foo?key=value" });
+
+ const { result } = renderHook(() => useSearch(), {
+ wrapper: (props) => {
+ return {props.children};
+ },
+ });
+
+ expect(result.current).toEqual("key=value");
+});
+
it("unescapes search string", () => {
const { result: searchResult } = renderHook(() => useSearch());
diff --git a/packages/wouter/types/memory-location.d.ts b/packages/wouter/types/memory-location.d.ts
index 5563903..665e131 100644
--- a/packages/wouter/types/memory-location.d.ts
+++ b/packages/wouter/types/memory-location.d.ts
@@ -1,20 +1,22 @@
-import { BaseLocationHook, Path } from "./location-hook.js";
+import { BaseLocationHook, BaseSearchHook, Path, SearchString } from "./location-hook.js";
type Navigate = (
to: Path,
options?: { replace?: boolean; state?: S }
) => void;
-type HookReturnValue = { hook: BaseLocationHook; navigate: Navigate };
+type HookReturnValue = { hook: BaseLocationHook; searchHook: BaseSearchHook, navigate: Navigate };
type StubHistory = { history: Path[]; reset: () => void };
export function memoryLocation(options?: {
path?: Path;
+ searchPath?: SearchString;
static?: boolean;
record?: false;
}): HookReturnValue;
export function memoryLocation(options?: {
path?: Path;
+ searchPath?: SearchString;
static?: boolean;
record: true;
}): HookReturnValue & StubHistory;