@qwik.dev/router 2.0.0-beta.5 → 2.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/adapters/static/vite.d.ts +1 -1
  2. package/lib/adapters/azure-swa/vite/index.d.ts +2 -2
  3. package/lib/adapters/bun-server/vite/index.d.ts +2 -2
  4. package/lib/adapters/cloud-run/vite/index.d.ts +2 -2
  5. package/lib/adapters/cloudflare-pages/vite/index.d.ts +2 -2
  6. package/lib/adapters/deno-server/vite/index.d.ts +2 -2
  7. package/lib/adapters/netlify-edge/vite/index.cjs +1 -0
  8. package/lib/adapters/netlify-edge/vite/index.d.ts +2 -2
  9. package/lib/adapters/netlify-edge/vite/index.mjs +1 -0
  10. package/lib/adapters/node-server/vite/index.d.ts +2 -2
  11. package/lib/adapters/shared/vite/index.cjs +88 -128
  12. package/lib/adapters/shared/vite/index.d.ts +9 -15
  13. package/lib/adapters/shared/vite/index.mjs +88 -124
  14. package/lib/adapters/{static → ssg}/vite/index.cjs +95 -124
  15. package/lib/adapters/ssg/vite/index.d.ts +13 -0
  16. package/lib/adapters/{static → ssg}/vite/index.mjs +93 -123
  17. package/lib/adapters/vercel-edge/vite/index.d.ts +2 -2
  18. package/lib/index.d.ts +161 -48
  19. package/lib/index.qwik.cjs +86 -23
  20. package/lib/index.qwik.mjs +88 -25
  21. package/lib/middleware/aws-lambda/index.d.ts +3 -2
  22. package/lib/middleware/aws-lambda/index.mjs +2 -4
  23. package/lib/middleware/azure-swa/index.mjs +6 -6
  24. package/lib/middleware/bun/index.mjs +4 -6
  25. package/lib/middleware/cloudflare-pages/index.mjs +4 -6
  26. package/lib/middleware/deno/index.mjs +8 -7
  27. package/lib/middleware/firebase/index.mjs +1 -3
  28. package/lib/middleware/netlify-edge/index.mjs +7 -6
  29. package/lib/middleware/node/index.cjs +4 -8
  30. package/lib/middleware/node/index.mjs +7 -7
  31. package/lib/middleware/request-handler/index.cjs +331 -268
  32. package/lib/middleware/request-handler/index.d.ts +56 -49
  33. package/lib/middleware/request-handler/index.mjs +335 -264
  34. package/lib/middleware/vercel-edge/index.mjs +7 -6
  35. package/lib/modules.d.ts +4 -12
  36. package/lib/{static → ssg}/deno.mjs +1 -1
  37. package/lib/{static → ssg}/index.cjs +1 -1
  38. package/lib/{static → ssg}/index.d.ts +17 -17
  39. package/lib/{static → ssg}/index.mjs +1 -1
  40. package/lib/{static → ssg}/node.cjs +16 -16
  41. package/lib/{static → ssg}/node.mjs +15 -15
  42. package/lib/vite/index.cjs +10260 -10437
  43. package/lib/vite/index.mjs +8220 -8387
  44. package/modules.d.ts +4 -12
  45. package/package.json +19 -8
  46. package/ssg.d.ts +2 -0
  47. package/static.d.ts +1 -1
  48. package/lib/adapters/static/vite/index.d.ts +0 -10
  49. package/middleware/request-handler/generated/not-found-paths.ts +0 -7
  50. package/middleware/request-handler/generated/static-paths.ts +0 -35
@@ -7,6 +7,7 @@ const internal = require("@qwik.dev/core/internal");
7
7
  const qwikRouterConfig = require("@qwik-router-config");
8
8
  const zod = require("zod");
9
9
  const swRegister = require("@qwik-router-sw-register");
10
+ const server = require("@qwik.dev/core/server");
10
11
  function _interopNamespaceDefault(e) {
11
12
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
12
13
  if (e) {
@@ -145,7 +146,7 @@ const getFetchOptions = (action, noCache) => {
145
146
  method: "POST",
146
147
  body: JSON.stringify(actionData),
147
148
  headers: {
148
- "Content-Type": "application/json, charset=UTF-8"
149
+ "Content-Type": "application/json; charset=UTF-8"
149
150
  }
150
151
  };
151
152
  }
@@ -366,8 +367,8 @@ const Link = core.component$((props) => {
366
367
  children: /* @__PURE__ */ jsxRuntime.jsx(core.Slot, {})
367
368
  });
368
369
  });
369
- const resolveHead = (endpoint, routeLocation, contentModules, locale) => {
370
- const head = createDocumentHead();
370
+ const resolveHead = (endpoint, routeLocation, contentModules, locale, defaults) => {
371
+ const head = createDocumentHead(defaults);
371
372
  const getData = (loaderOrAction) => {
372
373
  const id = loaderOrAction.__id;
373
374
  if (loaderOrAction.__brand === "server_loader") {
@@ -423,13 +424,23 @@ const mergeArray = (existingArr, newArr) => {
423
424
  }
424
425
  }
425
426
  };
426
- const createDocumentHead = () => ({
427
- title: "",
428
- meta: [],
429
- links: [],
430
- styles: [],
431
- scripts: [],
432
- frontmatter: {}
427
+ const createDocumentHead = (defaults) => ({
428
+ title: defaults?.title || "",
429
+ meta: [
430
+ ...defaults?.meta || []
431
+ ],
432
+ links: [
433
+ ...defaults?.links || []
434
+ ],
435
+ styles: [
436
+ ...defaults?.styles || []
437
+ ],
438
+ scripts: [
439
+ ...defaults?.scripts || []
440
+ ],
441
+ frontmatter: {
442
+ ...defaults?.frontmatter
443
+ }
433
444
  });
434
445
  function matchRoute(route, path) {
435
446
  const routeIdx = startIdxSkipSlash(route);
@@ -841,11 +852,11 @@ const preventNav = {};
841
852
  const internalState = {
842
853
  navCount: 0
843
854
  };
844
- const QwikRouterProvider = core.component$((props) => {
855
+ const useQwikRouter = (props) => {
845
856
  core.useStyles$(`
846
857
  @layer qwik {
847
858
  @supports selector(html:active-view-transition-type(type)) {
848
- html:active-view-transition-type(qwik-router-spa) {
859
+ html:active-view-transition-type(qwik-navigation) {
849
860
  :root{view-transition-name:none}
850
861
  }
851
862
  }
@@ -862,6 +873,7 @@ const QwikRouterProvider = core.component$((props) => {
862
873
  if (!urlEnv) {
863
874
  throw new Error(`Missing Qwik URL Env Data`);
864
875
  }
876
+ const serverHead = core.useServerData("documentHead");
865
877
  if (core.isServer) {
866
878
  if (env.ev.originalUrl.pathname !== env.ev.url.pathname && !__EXPERIMENTAL__.enableRequestRewrite) {
867
879
  throw new Error(`enableRequestRewrite is an experimental feature and is not enabled. Please enable the feature flag by adding \`experimental: ["enableRequestRewrite"]\` to your qwikVite plugin options.`);
@@ -901,7 +913,7 @@ const QwikRouterProvider = core.component$((props) => {
901
913
  replaceState: false,
902
914
  scroll: true
903
915
  });
904
- const documentHead = core.useStore(createDocumentHead);
916
+ const documentHead = core.useStore(() => createDocumentHead(serverHead));
905
917
  const content = core.useStore({
906
918
  headings: void 0,
907
919
  menu: void 0
@@ -1047,10 +1059,10 @@ const QwikRouterProvider = core.component$((props) => {
1047
1059
  } else {
1048
1060
  trackUrl = new URL(navigation.dest, location);
1049
1061
  if (trackUrl.pathname.endsWith("/")) {
1050
- if (!qwikRouterConfig__namespace.trailingSlash) {
1062
+ if (globalThis.__NO_TRAILING_SLASH__) {
1051
1063
  trackUrl.pathname = trackUrl.pathname.slice(0, -1);
1052
1064
  }
1053
- } else if (qwikRouterConfig__namespace.trailingSlash) {
1065
+ } else if (!globalThis.__NO_TRAILING_SLASH__) {
1054
1066
  trackUrl.pathname += "/";
1055
1067
  }
1056
1068
  let loadRoutePromise = loadRoute(qwikRouterConfig__namespace.routes, qwikRouterConfig__namespace.menus, qwikRouterConfig__namespace.cacheModules, trackUrl.pathname);
@@ -1092,8 +1104,7 @@ const QwikRouterProvider = core.component$((props) => {
1092
1104
  const [routeName, params, mods, menu] = loadedRoute;
1093
1105
  const contentModules = mods;
1094
1106
  const pageModule = contentModules[contentModules.length - 1];
1095
- const isRedirect = navType === "form" && !isSamePath(trackUrl, prevUrl);
1096
- if (navigation.dest.search && !isRedirect) {
1107
+ if (navigation.dest.search && !!isSamePath(trackUrl, prevUrl)) {
1097
1108
  trackUrl.search = navigation.dest.search;
1098
1109
  }
1099
1110
  if (!isSamePath(trackUrl, prevUrl)) {
@@ -1107,7 +1118,7 @@ const QwikRouterProvider = core.component$((props) => {
1107
1118
  type: navType,
1108
1119
  dest: trackUrl
1109
1120
  };
1110
- const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale);
1121
+ const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale, serverHead);
1111
1122
  content.headings = pageModule.headings;
1112
1123
  content.menu = menu;
1113
1124
  contentInternal.value = core.noSerialize(contentModules);
@@ -1123,7 +1134,7 @@ const QwikRouterProvider = core.component$((props) => {
1123
1134
  scrollState = getScrollHistory();
1124
1135
  }
1125
1136
  const scroller = document.getElementById(QWIK_ROUTER_SCROLLER) ?? document.documentElement;
1126
- if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || isRedirect) {
1137
+ if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || navType === "form" && !isSamePath(trackUrl, prevUrl)) {
1127
1138
  document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
1128
1139
  }
1129
1140
  const loaders = clientPageData?.loaders;
@@ -1255,7 +1266,7 @@ const QwikRouterProvider = core.component$((props) => {
1255
1266
  return internal._waitUntilRendered(elm);
1256
1267
  };
1257
1268
  const _waitNextPage = () => {
1258
- if (core.isServer || props.viewTransition === false) {
1269
+ if (core.isServer || props?.viewTransition === false) {
1259
1270
  return navigate();
1260
1271
  } else {
1261
1272
  const viewTransition = startViewTransition({
@@ -1291,10 +1302,13 @@ const QwikRouterProvider = core.component$((props) => {
1291
1302
  run();
1292
1303
  }
1293
1304
  });
1305
+ };
1306
+ const QwikRouterProvider = core.component$((props) => {
1307
+ useQwikRouter(props);
1294
1308
  return /* @__PURE__ */ jsxRuntime.jsx(core.Slot, {});
1295
1309
  });
1296
1310
  const QwikCityProvider = QwikRouterProvider;
1297
- const QwikRouterMockProvider = core.component$((props) => {
1311
+ const useQwikMockRouter = (props) => {
1298
1312
  const urlEnv = props.url ?? "http://localhost/";
1299
1313
  const url = new URL(urlEnv);
1300
1314
  const routeLocation = core.useStore({
@@ -1332,6 +1346,9 @@ const QwikRouterMockProvider = core.component$((props) => {
1332
1346
  core.useContextProvider(RouteStateContext, loaderState);
1333
1347
  core.useContextProvider(RouteActionContext, actionState);
1334
1348
  core.useContextProvider(RouteInternalContext, routeInternal);
1349
+ };
1350
+ const QwikRouterMockProvider = core.component$((props) => {
1351
+ useQwikMockRouter(props);
1335
1352
  return /* @__PURE__ */ jsxRuntime.jsx(core.Slot, {});
1336
1353
  });
1337
1354
  const QwikCityMockProvider = QwikRouterMockProvider;
@@ -1552,8 +1569,7 @@ const globalAction$ = /* @__PURE__ */ core.implicit$FirstArg(globalActionQrl);
1552
1569
  const routeLoaderQrl = (loaderQrl, ...rest) => {
1553
1570
  const { id, validators, serializationStrategy } = getValidators(rest, loaderQrl);
1554
1571
  function loader() {
1555
- const iCtx = internal._useInvokeContext();
1556
- const state = iCtx.$container$.resolveContext(iCtx.$hostElement$, RouteStateContext);
1572
+ const state = internal._resolveContextWithoutSequentialScope(RouteStateContext);
1557
1573
  if (!(id in state)) {
1558
1574
  throw new Error(`routeLoader$ "${loaderQrl.getSymbol()}" was invoked in a route where it was not declared.
1559
1575
  This is because the routeLoader$ was not exported in a 'layout.tsx' or 'index.tsx' file of the existing route.
@@ -1983,10 +1999,55 @@ function omitProps(obj, keys) {
1983
1999
  }
1984
2000
  return omittedObj;
1985
2001
  }
2002
+ const createRenderer = (getOptions) => {
2003
+ return (opts) => {
2004
+ const { jsx, options } = getOptions(opts);
2005
+ return server.renderToStream(jsx, options);
2006
+ };
2007
+ };
2008
+ const DocumentHeadTags = core.component$((props) => {
2009
+ let head = useDocumentHead();
2010
+ if (props) {
2011
+ head = {
2012
+ ...head,
2013
+ ...props
2014
+ };
2015
+ }
2016
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
2017
+ children: [
2018
+ head.title && /* @__PURE__ */ jsxRuntime.jsx("title", {
2019
+ children: head.title
2020
+ }),
2021
+ head.meta.map((m) => /* @__PURE__ */ jsxRuntime.jsx("meta", {
2022
+ ...m
2023
+ })),
2024
+ head.links.map((l) => /* @__PURE__ */ jsxRuntime.jsx("link", {
2025
+ ...l
2026
+ })),
2027
+ head.styles.map((s) => {
2028
+ const props2 = s.props || s;
2029
+ return /* @__PURE__ */ core.createElement("style", {
2030
+ ...props2,
2031
+ dangerouslySetInnerHTML: s.style || props2.dangerouslySetInnerHTML,
2032
+ key: s.key
2033
+ });
2034
+ }),
2035
+ head.scripts.map((s) => {
2036
+ const props2 = s.props || s;
2037
+ return /* @__PURE__ */ core.createElement("script", {
2038
+ ...props2,
2039
+ dangerouslySetInnerHTML: s.script || props2.dangerouslySetInnerHTML,
2040
+ key: s.key
2041
+ });
2042
+ })
2043
+ ]
2044
+ });
2045
+ });
1986
2046
  Object.defineProperty(exports, "z", {
1987
2047
  enumerable: true,
1988
2048
  get: () => zod.z
1989
2049
  });
2050
+ exports.DocumentHeadTags = DocumentHeadTags;
1990
2051
  exports.ErrorBoundary = ErrorBoundary;
1991
2052
  exports.Form = Form;
1992
2053
  exports.Link = Link;
@@ -1998,6 +2059,7 @@ exports.QwikRouterMockProvider = QwikRouterMockProvider;
1998
2059
  exports.QwikRouterProvider = QwikRouterProvider;
1999
2060
  exports.RouterOutlet = RouterOutlet;
2000
2061
  exports.ServiceWorkerRegister = ServiceWorkerRegister;
2062
+ exports.createRenderer = createRenderer;
2001
2063
  exports.globalAction$ = globalAction$;
2002
2064
  exports.globalActionQrl = globalActionQrl;
2003
2065
  exports.omitProps = omitProps;
@@ -2014,6 +2076,7 @@ exports.useLocation = useLocation;
2014
2076
  exports.useNavigate = useNavigate;
2015
2077
  exports.usePreventNavigate$ = usePreventNavigate$;
2016
2078
  exports.usePreventNavigateQrl = usePreventNavigateQrl;
2079
+ exports.useQwikRouter = useQwikRouter;
2017
2080
  exports.valibot$ = valibot$;
2018
2081
  exports.valibotQrl = valibotQrl;
2019
2082
  exports.validator$ = validator$;
@@ -1,11 +1,12 @@
1
1
  import { jsx, Fragment, jsxs } from "@qwik.dev/core/jsx-runtime";
2
- import { component$, useErrorBoundary, useOnWindow, $, Slot, createAsyncComputed$, isBrowser, createContextId, implicit$FirstArg, useContext, useVisibleTask$, noSerialize, useServerData, useSignal, untrack, sync$, isDev, withLocale, event$, useStyles$, isServer, useStore, useContextProvider, useTask$, getLocale, jsx as jsx$1, SkipRender } from "@qwik.dev/core";
2
+ import { component$, useErrorBoundary, useOnWindow, $, Slot, createAsyncComputed$, isBrowser, createContextId, implicit$FirstArg, useContext, useVisibleTask$, noSerialize, useServerData, useSignal, untrack, sync$, isDev, withLocale, event$, useStyles$, isServer, useStore, useContextProvider, useTask$, getLocale, jsx as jsx$1, SkipRender, createElement } from "@qwik.dev/core";
3
3
  import { p } from "@qwik.dev/core/preloader";
4
- import { _deserialize, _UNINITIALIZED, _getContextContainer, SerializerSymbol, _getContextElement, _getQContainerElement, _waitUntilRendered, _useInvokeContext, _getContextEvent, _serialize } from "@qwik.dev/core/internal";
4
+ import { _deserialize, _UNINITIALIZED, _getContextContainer, SerializerSymbol, _getContextElement, _getQContainerElement, _waitUntilRendered, _resolveContextWithoutSequentialScope, _getContextEvent, _serialize } from "@qwik.dev/core/internal";
5
5
  import * as qwikRouterConfig from "@qwik-router-config";
6
6
  import { z } from "zod";
7
7
  import { z as z2 } from "zod";
8
8
  import swRegister from "@qwik-router-sw-register";
9
+ import { renderToStream } from "@qwik.dev/core/server";
9
10
  const ErrorBoundary = component$((props) => {
10
11
  const store2 = useErrorBoundary();
11
12
  useOnWindow("qerror", $((e) => {
@@ -127,7 +128,7 @@ const getFetchOptions = (action, noCache) => {
127
128
  method: "POST",
128
129
  body: JSON.stringify(actionData),
129
130
  headers: {
130
- "Content-Type": "application/json, charset=UTF-8"
131
+ "Content-Type": "application/json; charset=UTF-8"
131
132
  }
132
133
  };
133
134
  }
@@ -348,8 +349,8 @@ const Link = component$((props) => {
348
349
  children: /* @__PURE__ */ jsx(Slot, {})
349
350
  });
350
351
  });
351
- const resolveHead = (endpoint, routeLocation, contentModules, locale) => {
352
- const head = createDocumentHead();
352
+ const resolveHead = (endpoint, routeLocation, contentModules, locale, defaults) => {
353
+ const head = createDocumentHead(defaults);
353
354
  const getData = (loaderOrAction) => {
354
355
  const id = loaderOrAction.__id;
355
356
  if (loaderOrAction.__brand === "server_loader") {
@@ -405,13 +406,23 @@ const mergeArray = (existingArr, newArr) => {
405
406
  }
406
407
  }
407
408
  };
408
- const createDocumentHead = () => ({
409
- title: "",
410
- meta: [],
411
- links: [],
412
- styles: [],
413
- scripts: [],
414
- frontmatter: {}
409
+ const createDocumentHead = (defaults) => ({
410
+ title: defaults?.title || "",
411
+ meta: [
412
+ ...defaults?.meta || []
413
+ ],
414
+ links: [
415
+ ...defaults?.links || []
416
+ ],
417
+ styles: [
418
+ ...defaults?.styles || []
419
+ ],
420
+ scripts: [
421
+ ...defaults?.scripts || []
422
+ ],
423
+ frontmatter: {
424
+ ...defaults?.frontmatter
425
+ }
415
426
  });
416
427
  function matchRoute(route, path) {
417
428
  const routeIdx = startIdxSkipSlash(route);
@@ -823,11 +834,11 @@ const preventNav = {};
823
834
  const internalState = {
824
835
  navCount: 0
825
836
  };
826
- const QwikRouterProvider = component$((props) => {
837
+ const useQwikRouter = (props) => {
827
838
  useStyles$(`
828
839
  @layer qwik {
829
840
  @supports selector(html:active-view-transition-type(type)) {
830
- html:active-view-transition-type(qwik-router-spa) {
841
+ html:active-view-transition-type(qwik-navigation) {
831
842
  :root{view-transition-name:none}
832
843
  }
833
844
  }
@@ -844,6 +855,7 @@ const QwikRouterProvider = component$((props) => {
844
855
  if (!urlEnv) {
845
856
  throw new Error(`Missing Qwik URL Env Data`);
846
857
  }
858
+ const serverHead = useServerData("documentHead");
847
859
  if (isServer) {
848
860
  if (env.ev.originalUrl.pathname !== env.ev.url.pathname && !__EXPERIMENTAL__.enableRequestRewrite) {
849
861
  throw new Error(`enableRequestRewrite is an experimental feature and is not enabled. Please enable the feature flag by adding \`experimental: ["enableRequestRewrite"]\` to your qwikVite plugin options.`);
@@ -883,7 +895,7 @@ const QwikRouterProvider = component$((props) => {
883
895
  replaceState: false,
884
896
  scroll: true
885
897
  });
886
- const documentHead = useStore(createDocumentHead);
898
+ const documentHead = useStore(() => createDocumentHead(serverHead));
887
899
  const content = useStore({
888
900
  headings: void 0,
889
901
  menu: void 0
@@ -1029,10 +1041,10 @@ const QwikRouterProvider = component$((props) => {
1029
1041
  } else {
1030
1042
  trackUrl = new URL(navigation.dest, location);
1031
1043
  if (trackUrl.pathname.endsWith("/")) {
1032
- if (!qwikRouterConfig.trailingSlash) {
1044
+ if (globalThis.__NO_TRAILING_SLASH__) {
1033
1045
  trackUrl.pathname = trackUrl.pathname.slice(0, -1);
1034
1046
  }
1035
- } else if (qwikRouterConfig.trailingSlash) {
1047
+ } else if (!globalThis.__NO_TRAILING_SLASH__) {
1036
1048
  trackUrl.pathname += "/";
1037
1049
  }
1038
1050
  let loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, trackUrl.pathname);
@@ -1074,8 +1086,7 @@ const QwikRouterProvider = component$((props) => {
1074
1086
  const [routeName, params, mods, menu] = loadedRoute;
1075
1087
  const contentModules = mods;
1076
1088
  const pageModule = contentModules[contentModules.length - 1];
1077
- const isRedirect = navType === "form" && !isSamePath(trackUrl, prevUrl);
1078
- if (navigation.dest.search && !isRedirect) {
1089
+ if (navigation.dest.search && !!isSamePath(trackUrl, prevUrl)) {
1079
1090
  trackUrl.search = navigation.dest.search;
1080
1091
  }
1081
1092
  if (!isSamePath(trackUrl, prevUrl)) {
@@ -1089,7 +1100,7 @@ const QwikRouterProvider = component$((props) => {
1089
1100
  type: navType,
1090
1101
  dest: trackUrl
1091
1102
  };
1092
- const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale);
1103
+ const resolvedHead = resolveHead(clientPageData, routeLocation, contentModules, locale, serverHead);
1093
1104
  content.headings = pageModule.headings;
1094
1105
  content.menu = menu;
1095
1106
  contentInternal.value = noSerialize(contentModules);
@@ -1105,7 +1116,7 @@ const QwikRouterProvider = component$((props) => {
1105
1116
  scrollState = getScrollHistory();
1106
1117
  }
1107
1118
  const scroller = document.getElementById(QWIK_ROUTER_SCROLLER) ?? document.documentElement;
1108
- if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || isRedirect) {
1119
+ if (navigation.scroll && (!navigation.forceReload || !isSamePath(trackUrl, prevUrl)) && (navType === "link" || navType === "popstate") || navType === "form" && !isSamePath(trackUrl, prevUrl)) {
1109
1120
  document.__q_scroll_restore__ = () => restoreScroll(navType, trackUrl, prevUrl, scroller, scrollState);
1110
1121
  }
1111
1122
  const loaders = clientPageData?.loaders;
@@ -1237,7 +1248,7 @@ const QwikRouterProvider = component$((props) => {
1237
1248
  return _waitUntilRendered(elm);
1238
1249
  };
1239
1250
  const _waitNextPage = () => {
1240
- if (isServer || props.viewTransition === false) {
1251
+ if (isServer || props?.viewTransition === false) {
1241
1252
  return navigate();
1242
1253
  } else {
1243
1254
  const viewTransition = startViewTransition({
@@ -1273,10 +1284,13 @@ const QwikRouterProvider = component$((props) => {
1273
1284
  run();
1274
1285
  }
1275
1286
  });
1287
+ };
1288
+ const QwikRouterProvider = component$((props) => {
1289
+ useQwikRouter(props);
1276
1290
  return /* @__PURE__ */ jsx(Slot, {});
1277
1291
  });
1278
1292
  const QwikCityProvider = QwikRouterProvider;
1279
- const QwikRouterMockProvider = component$((props) => {
1293
+ const useQwikMockRouter = (props) => {
1280
1294
  const urlEnv = props.url ?? "http://localhost/";
1281
1295
  const url = new URL(urlEnv);
1282
1296
  const routeLocation = useStore({
@@ -1314,6 +1328,9 @@ const QwikRouterMockProvider = component$((props) => {
1314
1328
  useContextProvider(RouteStateContext, loaderState);
1315
1329
  useContextProvider(RouteActionContext, actionState);
1316
1330
  useContextProvider(RouteInternalContext, routeInternal);
1331
+ };
1332
+ const QwikRouterMockProvider = component$((props) => {
1333
+ useQwikMockRouter(props);
1317
1334
  return /* @__PURE__ */ jsx(Slot, {});
1318
1335
  });
1319
1336
  const QwikCityMockProvider = QwikRouterMockProvider;
@@ -1534,8 +1551,7 @@ const globalAction$ = /* @__PURE__ */ implicit$FirstArg(globalActionQrl);
1534
1551
  const routeLoaderQrl = (loaderQrl, ...rest) => {
1535
1552
  const { id, validators, serializationStrategy } = getValidators(rest, loaderQrl);
1536
1553
  function loader() {
1537
- const iCtx = _useInvokeContext();
1538
- const state = iCtx.$container$.resolveContext(iCtx.$hostElement$, RouteStateContext);
1554
+ const state = _resolveContextWithoutSequentialScope(RouteStateContext);
1539
1555
  if (!(id in state)) {
1540
1556
  throw new Error(`routeLoader$ "${loaderQrl.getSymbol()}" was invoked in a route where it was not declared.
1541
1557
  This is because the routeLoader$ was not exported in a 'layout.tsx' or 'index.tsx' file of the existing route.
@@ -1965,7 +1981,52 @@ function omitProps(obj, keys) {
1965
1981
  }
1966
1982
  return omittedObj;
1967
1983
  }
1984
+ const createRenderer = (getOptions) => {
1985
+ return (opts) => {
1986
+ const { jsx: jsx2, options } = getOptions(opts);
1987
+ return renderToStream(jsx2, options);
1988
+ };
1989
+ };
1990
+ const DocumentHeadTags = component$((props) => {
1991
+ let head = useDocumentHead();
1992
+ if (props) {
1993
+ head = {
1994
+ ...head,
1995
+ ...props
1996
+ };
1997
+ }
1998
+ return /* @__PURE__ */ jsxs(Fragment, {
1999
+ children: [
2000
+ head.title && /* @__PURE__ */ jsx("title", {
2001
+ children: head.title
2002
+ }),
2003
+ head.meta.map((m) => /* @__PURE__ */ jsx("meta", {
2004
+ ...m
2005
+ })),
2006
+ head.links.map((l) => /* @__PURE__ */ jsx("link", {
2007
+ ...l
2008
+ })),
2009
+ head.styles.map((s) => {
2010
+ const props2 = s.props || s;
2011
+ return /* @__PURE__ */ createElement("style", {
2012
+ ...props2,
2013
+ dangerouslySetInnerHTML: s.style || props2.dangerouslySetInnerHTML,
2014
+ key: s.key
2015
+ });
2016
+ }),
2017
+ head.scripts.map((s) => {
2018
+ const props2 = s.props || s;
2019
+ return /* @__PURE__ */ createElement("script", {
2020
+ ...props2,
2021
+ dangerouslySetInnerHTML: s.script || props2.dangerouslySetInnerHTML,
2022
+ key: s.key
2023
+ });
2024
+ })
2025
+ ]
2026
+ });
2027
+ });
1968
2028
  export {
2029
+ DocumentHeadTags,
1969
2030
  ErrorBoundary,
1970
2031
  Form,
1971
2032
  Link,
@@ -1977,6 +2038,7 @@ export {
1977
2038
  QwikRouterProvider,
1978
2039
  RouterOutlet,
1979
2040
  ServiceWorkerRegister,
2041
+ createRenderer,
1980
2042
  globalAction$,
1981
2043
  globalActionQrl,
1982
2044
  omitProps,
@@ -1993,6 +2055,7 @@ export {
1993
2055
  useNavigate,
1994
2056
  usePreventNavigate$,
1995
2057
  usePreventNavigateQrl,
2058
+ useQwikRouter,
1996
2059
  valibot$,
1997
2060
  valibotQrl,
1998
2061
  validator$,
@@ -11,8 +11,9 @@ import { ServerResponse } from 'http';
11
11
  declare interface AwsOpt {
12
12
  render: Render;
13
13
  manifest?: QwikManifest;
14
- qwikRouterConfig: QwikRouterConfig;
15
- /** @deprecated Use `QwikRouterConfig` instead. Will be removed in V3 */
14
+ /** @deprecated Not used */
15
+ qwikRouterConfig?: QwikRouterConfig;
16
+ /** @deprecated Not used */
16
17
  qwikCityPlan?: QwikCityPlan;
17
18
  }
18
19
 
@@ -2,10 +2,8 @@
2
2
  import { createQwikRouter as createQwikRouterNode } from "@qwik.dev/router/middleware/node";
3
3
  function createQwikRouter(opts) {
4
4
  if (opts.qwikCityPlan && !opts.qwikRouterConfig) {
5
- console.warn("qwikCityPlan is deprecated. Use qwikRouterConfig instead.");
5
+ console.warn("qwikCityPlan is deprecated. Simply remove it.");
6
6
  opts.qwikRouterConfig = opts.qwikCityPlan;
7
- } else if (!opts.qwikRouterConfig) {
8
- throw new Error("qwikRouterConfig is required.");
9
7
  }
10
8
  try {
11
9
  const { router, staticFile, notFound } = createQwikRouterNode({
@@ -23,7 +21,7 @@ function createQwikRouter(opts) {
23
21
  }
24
22
  });
25
23
  const fixPath = (pathT) => {
26
- if (opts.qwikRouterConfig.trailingSlash) {
24
+ if (!globalThis.__NO_TRAILING_SLASH__) {
27
25
  const url = new URL(pathT, "http://aws-qwik.local");
28
26
  if (url.pathname.includes(".", url.pathname.lastIndexOf("/"))) {
29
27
  return pathT;
@@ -194,17 +194,17 @@ var require_set_cookie = __commonJS({
194
194
 
195
195
  // packages/qwik-router/src/middleware/azure-swa/index.ts
196
196
  var import_set_cookie_parser = __toESM(require_set_cookie(), 1);
197
- import { getNotFound } from "@qwik-router-not-found-paths";
198
- import { isStaticPath } from "@qwik-router-static-paths";
199
197
  import { _deserialize, _serialize, _verifySerializable } from "@qwik.dev/core/internal";
200
198
  import { setServerPlatform } from "@qwik.dev/core/server";
201
- import { requestHandler } from "../request-handler/index.mjs";
199
+ import {
200
+ getNotFound,
201
+ isStaticPath,
202
+ requestHandler
203
+ } from "../request-handler/index.mjs";
202
204
  function createQwikRouter(opts) {
203
205
  if (opts.qwikCityPlan && !opts.qwikRouterConfig) {
204
- console.warn("qwikCityPlan is deprecated. Use qwikRouterConfig instead.");
206
+ console.warn("qwikCityPlan is deprecated. Simply remove it.");
205
207
  opts.qwikRouterConfig = opts.qwikCityPlan;
206
- } else if (!opts.qwikRouterConfig) {
207
- throw new Error("qwikRouterConfig is required.");
208
208
  }
209
209
  const qwikSerializer = {
210
210
  _deserialize,
@@ -1,10 +1,10 @@
1
1
  // packages/qwik-router/src/middleware/bun/index.ts
2
- import { getNotFound } from "@qwik-router-not-found-paths";
3
- import { isStaticPath } from "@qwik-router-static-paths";
4
2
  import { _deserialize, _serialize, _verifySerializable } from "@qwik.dev/core/internal";
5
3
  import { setServerPlatform } from "@qwik.dev/core/server";
6
4
  import {
7
5
  _TextEncoderStream_polyfill,
6
+ getNotFound,
7
+ isStaticPath,
8
8
  mergeHeadersCookies,
9
9
  requestHandler
10
10
  } from "../request-handler/index.mjs";
@@ -66,10 +66,8 @@ var MIME_TYPES = {
66
66
  function createQwikRouter(opts) {
67
67
  var _a;
68
68
  if (opts.qwikCityPlan && !opts.qwikRouterConfig) {
69
- console.warn("qwikCityPlan is deprecated. Use qwikRouterConfig instead.");
69
+ console.warn("qwikCityPlan is deprecated. Simply remove it.");
70
70
  opts.qwikRouterConfig = opts.qwikCityPlan;
71
- } else if (!opts.qwikRouterConfig) {
72
- throw new Error("qwikRouterConfig is required.");
73
71
  }
74
72
  globalThis.TextEncoderStream ||= _TextEncoderStream_polyfill;
75
73
  const qwikSerializer = { _deserialize, _serialize, _verifySerializable };
@@ -155,7 +153,7 @@ function createQwikRouter(opts) {
155
153
  let filePath;
156
154
  if (fileName.includes(".")) {
157
155
  filePath = join(staticFolder, pathname);
158
- } else if (opts.qwikRouterConfig.trailingSlash) {
156
+ } else if (!globalThis.__NO_TRAILING_SLASH__) {
159
157
  filePath = join(staticFolder, pathname + "index.html");
160
158
  } else {
161
159
  filePath = join(staticFolder, pathname, "index.html");
@@ -1,23 +1,21 @@
1
1
  // packages/qwik-router/src/middleware/cloudflare-pages/index.ts
2
- import { getNotFound } from "@qwik-router-not-found-paths";
3
- import { isStaticPath } from "@qwik-router-static-paths";
4
2
  import { _deserialize, _serialize, _verifySerializable } from "@qwik.dev/core/internal";
5
3
  import { setServerPlatform } from "@qwik.dev/core/server";
6
4
  import {
7
5
  _TextEncoderStream_polyfill,
6
+ getNotFound,
7
+ isStaticPath,
8
8
  mergeHeadersCookies,
9
9
  requestHandler
10
10
  } from "../request-handler/index.mjs";
11
11
  function createQwikRouter(opts) {
12
12
  if (opts.qwikCityPlan && !opts.qwikRouterConfig) {
13
- console.warn("qwikCityPlan is deprecated. Use qwikRouterConfig instead.");
13
+ console.warn("qwikCityPlan is deprecated. Simply remove it.");
14
14
  opts.qwikRouterConfig = opts.qwikCityPlan;
15
- } else if (!opts.qwikRouterConfig) {
16
- throw new Error("qwikRouterConfig is required.");
17
15
  }
18
16
  try {
19
17
  new globalThis.TextEncoderStream();
20
- } catch (e) {
18
+ } catch {
21
19
  globalThis.TextEncoderStream = _TextEncoderStream_polyfill;
22
20
  }
23
21
  const qwikSerializer = { _deserialize, _serialize, _verifySerializable };
@@ -1,9 +1,12 @@
1
1
  // packages/qwik-router/src/middleware/deno/index.ts
2
- import { getNotFound } from "@qwik-router-not-found-paths";
3
- import { isStaticPath } from "@qwik-router-static-paths";
4
2
  import { _deserialize, _serialize, _verifySerializable } from "@qwik.dev/core/internal";
5
3
  import { setServerPlatform } from "@qwik.dev/core/server";
6
- import { mergeHeadersCookies, requestHandler } from "../request-handler/index.mjs";
4
+ import {
5
+ getNotFound,
6
+ isStaticPath,
7
+ mergeHeadersCookies,
8
+ requestHandler
9
+ } from "../request-handler/index.mjs";
7
10
 
8
11
  // packages/qwik-router/src/middleware/request-handler/mime-types.ts
9
12
  var MIME_TYPES = {
@@ -62,10 +65,8 @@ import { extname, fromFileUrl, join } from "https://deno.land/std/path/mod.ts";
62
65
  function createQwikRouter(opts) {
63
66
  var _a;
64
67
  if (opts.qwikCityPlan && !opts.qwikRouterConfig) {
65
- console.warn("qwikCityPlan is deprecated. Use qwikRouterConfig instead.");
68
+ console.warn("qwikCityPlan is deprecated. Simply remove it.");
66
69
  opts.qwikRouterConfig = opts.qwikCityPlan;
67
- } else if (!opts.qwikRouterConfig) {
68
- throw new Error("qwikRouterConfig is required.");
69
70
  }
70
71
  const qwikSerializer = {
71
72
  _deserialize,
@@ -147,7 +148,7 @@ function createQwikRouter(opts) {
147
148
  let filePath;
148
149
  if (fileName.includes(".")) {
149
150
  filePath = join(staticFolder, pathname);
150
- } else if (opts.qwikRouterConfig.trailingSlash) {
151
+ } else if (!globalThis.__NO_TRAILING_SLASH__) {
151
152
  filePath = join(staticFolder, pathname + "index.html");
152
153
  } else {
153
154
  filePath = join(staticFolder, pathname, "index.html");
@@ -2,10 +2,8 @@
2
2
  import { createQwikRouter as createQwikRouterNode } from "@qwik.dev/router/middleware/node";
3
3
  function createQwikRouter(opts) {
4
4
  if (opts.qwikCityPlan && !opts.qwikRouterConfig) {
5
- console.warn("qwikCityPlan is deprecated. Use qwikRouterConfig instead.");
5
+ console.warn("qwikCityPlan is deprecated. Simply remove it.");
6
6
  opts.qwikRouterConfig = opts.qwikCityPlan;
7
- } else if (!opts.qwikRouterConfig) {
8
- throw new Error("qwikRouterConfig is required.");
9
7
  }
10
8
  const { staticFile, notFound, router } = createQwikRouterNode({
11
9
  render: opts.render,