Skip to content

Commit e94f8ef

Browse files
authored
Merge pull request #410 from Breek/hook
feat: add URL transformation hook
2 parents 3b97809 + 6740fe2 commit e94f8ef

File tree

6 files changed

+36
-10
lines changed

6 files changed

+36
-10
lines changed

.changeset/ten-trains-work.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@solidjs/router": patch
3+
---
4+
5+
Allow rewriting url

src/data/events.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { RouterContext } from "../types.js";
44
import { actions } from "./action.js";
55
import { mockBase } from "../utils.js";
66

7-
export function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "/_server") {
7+
export function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "/_server", transformUrl?: (url: string) => string) {
88
return (router: RouterContext) => {
99
const basePath = router.base.path();
1010
const navigateFromRoute = router.navigatorFactory(router.base);
@@ -71,6 +71,9 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
7171
const res = handleAnchor(evt as MouseEvent);
7272
if (!res) return;
7373
const [a, url] = res;
74+
if (typeof transformUrl === "function") {
75+
url.pathname = transformUrl(url.pathname);
76+
}
7477
if (!preloadTimeout[url.pathname])
7578
router.preloadRoute(url, a.getAttribute("preload") !== "false");
7679
}
@@ -79,6 +82,9 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
7982
const res = handleAnchor(evt as MouseEvent);
8083
if (!res) return;
8184
const [a, url] = res;
85+
if (typeof transformUrl === "function") {
86+
url.pathname = transformUrl(url.pathname);
87+
}
8288
if (preloadTimeout[url.pathname]) return;
8389
preloadTimeout[url.pathname] = setTimeout(() => {
8490
router.preloadRoute(url, a.getAttribute("preload") !== "false");
@@ -90,6 +96,9 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
9096
const res = handleAnchor(evt as MouseEvent);
9197
if (!res) return;
9298
const [, url] = res;
99+
if (typeof transformUrl === "function") {
100+
url.pathname = transformUrl(url.pathname);
101+
}
93102
if (preloadTimeout[url.pathname]) {
94103
clearTimeout(preloadTimeout[url.pathname]);
95104
delete preloadTimeout[url.pathname];

src/routers/Router.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ export type RouterProps = BaseRouterProps & { url?: string, actionBase?: string,
1010

1111
export function Router(props: RouterProps): JSX.Element {
1212
if (isServer) return StaticRouter(props);
13-
const getSource = () => ({
14-
value: window.location.pathname + window.location.search + window.location.hash,
15-
state: window.history.state
16-
});
13+
const getSource = () => {
14+
const url = window.location.pathname + window.location.search;
15+
return {
16+
value: props.transformUrl ? props.transformUrl(url) + window.location.hash : url + window.location.hash,
17+
state: window.history.state
18+
}
19+
};
1720
const beforeLeave = createBeforeLeave();
1821
return createRouter({
1922
get: getSource,
@@ -36,7 +39,7 @@ export function Router(props: RouterProps): JSX.Element {
3639
}
3740
})
3841
),
39-
create: setupNativeEvents(props.preload, props.explicitLinks, props.actionBase),
42+
create: setupNativeEvents(props.preload, props.explicitLinks, props.actionBase, props.transformUrl),
4043
utils: {
4144
go: delta => window.history.go(delta),
4245
beforeLeave

src/routers/StaticRouter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ export type StaticRouterProps = BaseRouterProps & { url?: string };
1111

1212
export function StaticRouter(props: StaticRouterProps): JSX.Element {
1313
let e;
14+
const url = props.url || ((e = getRequestEvent()) && getPath(e.request.url)) || ""
1415
const obj = {
15-
value: props.url || ((e = getRequestEvent()) && getPath(e.request.url)) || ""
16+
value: props.transformUrl ? props.transformUrl(url) : url,
1617
};
1718
return createRouterComponent({
1819
signal: [() => obj, next => Object.assign(obj, next)]

src/routers/components.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export type BaseRouterProps = {
4242
rootLoad?: RouteLoadFunc;
4343
singleFlight?: boolean;
4444
children?: JSX.Element | RouteDefinition | RouteDefinition[];
45+
transformUrl?: (url: string) => string;
4546
};
4647

4748
export const createRouterComponent = (router: RouterIntegration) => (props: BaseRouterProps) => {
@@ -54,7 +55,8 @@ export const createRouterComponent = (router: RouterIntegration) => (props: Base
5455
let context: Owner;
5556
const routerState = createRouterContext(router, branches, () => context, {
5657
base,
57-
singleFlight: props.singleFlight
58+
singleFlight: props.singleFlight,
59+
transformUrl: props.transformUrl,
5860
});
5961
router.create && router.create(routerState);
6062
return (

src/routing.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ export function createRouterContext(
280280
integration: RouterIntegration,
281281
branches: () => Branch[],
282282
getContext?: () => any,
283-
options: { base?: string; singleFlight?: boolean } = {}
283+
options: { base?: string; singleFlight?: boolean, transformUrl?: (url: string) => string } = {}
284284
): RouterContext {
285285
const {
286286
signal: [source, setSource],
@@ -313,7 +313,13 @@ export function createRouterContext(
313313
const referrers: LocationChange[] = [];
314314
const submissions = createSignal<Submission<any, any>[]>(isServer ? initFromFlash() : []);
315315

316-
const matches = createMemo(() => getRouteMatches(branches(), location.pathname));
316+
const matches = createMemo(() => {
317+
if (typeof options.transformUrl === "function") {
318+
return getRouteMatches(branches(), options.transformUrl(location.pathname));
319+
}
320+
321+
return getRouteMatches(branches(), location.pathname);
322+
});
317323

318324
const params = createMemoObject(() => {
319325
const m = matches();

0 commit comments

Comments
 (0)