Skip to content

Commit b472cdf

Browse files
committed
fix(router): properly init state browser-side
+ remove the unused context
1 parent 2a587f8 commit b472cdf

File tree

4 files changed

+29
-26
lines changed

4 files changed

+29
-26
lines changed

packages/qwik-router/src/runtime/src/contexts.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type {
77
RouteLocation,
88
RouteNavigate,
99
RoutePreventNavigate,
10-
RouteStateInternal,
1110
} from './types';
1211

1312
export const RouteStateContext =
@@ -25,8 +24,5 @@ export const RouteNavigateContext = /*#__PURE__*/ createContextId<RouteNavigate>
2524

2625
export const RouteActionContext = /*#__PURE__*/ createContextId<RouteAction>('qc-a');
2726

28-
export const RouteInternalContext =
29-
/*#__PURE__*/ createContextId<Signal<RouteStateInternal>>('qc-ir');
30-
3127
export const RoutePreventNavigateContext =
3228
/*#__PURE__*/ createContextId<RoutePreventNavigate>('qc-p');

packages/qwik-router/src/runtime/src/qwik-router-component.tsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import {
3636
ContentInternalContext,
3737
DocumentHeadContext,
3838
RouteActionContext,
39-
RouteInternalContext,
4039
RouteLocationContext,
4140
RouteNavigateContext,
4241
RoutePreventNavigateContext,
@@ -122,6 +121,11 @@ const internalState = { navCount: 0 };
122121
* This hook should be used once, at the root of your application.
123122
*/
124123
export const useQwikRouter = (props?: QwikRouterProps) => {
124+
if (!isServer) {
125+
throw new Error(
126+
'useQwikRouter can only run during SSR on the server. If you are seeing this, it means you are re-rendering the root of your application. Fix that or use the <QwikRouter> component around the root of your application.'
127+
);
128+
}
125129
useStyles$(transitionCss);
126130
const env = useQwikRouterEnv();
127131
if (!env?.params) {
@@ -136,15 +140,13 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
136140
}
137141
const serverHead = useServerData<DocumentHeadValue>('documentHead');
138142

139-
if (isServer) {
140-
if (
141-
env!.ev.originalUrl.pathname !== env!.ev.url.pathname &&
142-
!__EXPERIMENTAL__.enableRequestRewrite
143-
) {
144-
throw new Error(
145-
`enableRequestRewrite is an experimental feature and is not enabled. Please enable the feature flag by adding \`experimental: ["enableRequestRewrite"]\` to your qwikVite plugin options.`
146-
);
147-
}
143+
if (
144+
env.ev.originalUrl.pathname !== env.ev.url.pathname &&
145+
!__EXPERIMENTAL__.enableRequestRewrite
146+
) {
147+
throw new Error(
148+
`enableRequestRewrite is an experimental feature and is not enabled. Please enable the feature flag by adding \`experimental: ["enableRequestRewrite"]\` to your qwikVite plugin options.`
149+
);
148150
}
149151

150152
const url = new URL(urlEnv);
@@ -200,8 +202,6 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
200202
const routeInternal = useSignal<RouteStateInternal>({
201203
type: 'initial',
202204
dest: url,
203-
forceReload: false,
204-
replaceState: false,
205205
scroll: true,
206206
});
207207
const documentHead = useStore<Editable<ResolvedDocumentHead>>(() =>
@@ -283,7 +283,8 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
283283
// The initial value of routeInternal is derived from the server env,
284284
// which in the case of SSG may not match the actual origin the site
285285
// is deployed on.
286-
if (isBrowser && routeInternal.value.type === 'initial') {
286+
// We only do this for link navigations, as popstate will have already changed the URL
287+
if (isBrowser && type === 'link' && routeInternal.value.type === 'initial') {
287288
routeInternal.value.dest = new URL(window.location.href);
288289
}
289290

@@ -364,7 +365,13 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
364365
return;
365366
}
366367

367-
routeInternal.value = { type, dest, forceReload, replaceState, scroll };
368+
routeInternal.value = {
369+
type,
370+
dest,
371+
forceReload,
372+
replaceState,
373+
scroll,
374+
};
368375

369376
if (isBrowser) {
370377
loadClientData(dest, _getContextElement());
@@ -391,12 +398,12 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
391398
useContextProvider(RouteNavigateContext, goto);
392399
useContextProvider(RouteStateContext, loaderState);
393400
useContextProvider(RouteActionContext, actionState);
394-
useContextProvider(RouteInternalContext, routeInternal);
395401
useContextProvider<any>(RoutePreventNavigateContext, registerPreventNav);
396402

397403
useTask$(({ track }) => {
398404
async function run() {
399-
const [navigation, action] = track(() => [routeInternal.value, actionState.value]);
405+
const navigation = track(routeInternal);
406+
const action = track(actionState);
400407

401408
const locale = getLocale('');
402409
const prevUrl = routeLocation.url;
@@ -629,7 +636,7 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
629636
// Firefox only does it once and no more, but will still scroll. It also sets state to null.
630637
// Any <a> tags w/ #hash href will break SPA state in Firefox.
631638
// We patch these events and direct them to Link pipeline during SPA.
632-
document.body.addEventListener('click', (event) => {
639+
document.addEventListener('click', (event) => {
633640
if (event.defaultPrevented) {
634641
return;
635642
}
@@ -667,7 +674,7 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
667674
}
668675
});
669676

670-
document.body.removeEventListener('click', win._qRouterInitAnchors!);
677+
document.removeEventListener('click', win._qRouterInitAnchors!);
671678
win._qRouterInitAnchors = undefined;
672679

673680
// TODO Remove block after Navigation API PR.
@@ -783,6 +790,7 @@ export const useQwikRouter = (props?: QwikRouterProps) => {
783790
}
784791

785792
if (isServer) {
793+
// Server: wait for navigation to complete
786794
return run();
787795
} else {
788796
run();
@@ -830,7 +838,6 @@ const useQwikMockRouter = (props: QwikRouterMockProps) => {
830838
);
831839

832840
const loaderState = {};
833-
const routeInternal = useSignal<RouteStateInternal>({ type: 'initial', dest: url });
834841

835842
const goto: RouteNavigate =
836843
props.goto ??
@@ -859,7 +866,6 @@ const useQwikMockRouter = (props: QwikRouterMockProps) => {
859866
useContextProvider(RouteNavigateContext, goto);
860867
useContextProvider(RouteStateContext, loaderState);
861868
useContextProvider(RouteActionContext, actionState);
862-
useContextProvider(RouteInternalContext, routeInternal);
863869
};
864870

865871
/** @public */

packages/qwik-router/src/runtime/src/spa-init.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ export default event$((_: Event, el: Element) => {
200200
setTimeout(() => {
201201
win.addEventListener('popstate', win[initPopstate]!);
202202
win.addEventListener('scroll', win[initScroll]!, { passive: true });
203-
document.body.addEventListener('click', win[initAnchors]!);
203+
document.addEventListener('click', win[initAnchors]!);
204204

205205
if (!(win as any).navigation) {
206206
document.addEventListener('visibilitychange', win[initVisibility]!, {

packages/qwik/src/core/shared/scheduler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,8 @@ This is often caused by modifying a signal in an already rendered component duri
562562
})
563563
.catch((e) => {
564564
if (chore.$state$ !== ChoreState.RUNNING) {
565-
// we already handled the error
565+
// we already handled an error but maybe it's a different one so we log it
566+
console.error(e);
566567
return;
567568
}
568569
handleError(chore, e);

0 commit comments

Comments
 (0)