-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[✨] Critical DX/UX improvement to SPA navigation in Qwik City #3244
Conversation
Run & review this pull request in StackBlitz Codeflow. |
830e7f6
to
e36e111
Compare
Hi @billykwok 👋 thank you very much for creating this PR 🙏 I just have a question based on the description:
you mention, that the restore for MPA (popstate) navigations does not work atm, which i can't confirm so far. At least not on the available browsers 😄 The MPA navigation scroll position restoreMar-03-2023.13-13-31.mp4Is the description wrong in that case or do i miss something? 👼 |
Thanks for checking out my change. It is intended for SPA scrolling only. When I said popstate, I was referring to popstate navigation in SPA (e.g. same-page re-rendering due to pressing back button after pushState). MPA does not need manual scroll restoration because browsers handle it by default. Hope this clarifies the change. |
c16c48a
to
f22793c
Compare
f22793c
to
6608b43
Compare
Converted to draft for now as I found a new way to implement the change that is more flexible and robust. |
74ab896
to
5c68954
Compare
044ac09
to
bcda354
Compare
I just pushed an update to address all of the comments so far.
@manucorporat Thank you for spending time looking at it previously. Hope you manage to squeeze some time on it again. |
bcda354
to
e911ab4
Compare
…change' navigations in SPAs - Support MPA-like and customizable scroll restoration in SPA - Race condition when restoring scroll positions - Prevent full-page reload when popstate happens before manual navigation - Fix hash navigation in SPA
e911ab4
to
be86ddb
Compare
I want to merge this PR, but there are so problems, the thing i am more against is the usage of useVisibleTask and useWindowOn() in RouterOutlet, right now, QwikCity apps download no js, adding this changes the baseline, which affects demos and simple apps. |
Thanks for following up. I appreciate the pursuit of avoiding the initial JS load at all costs. However, there is probably no simple way to achieve the intended result of this PR with Qwik's current design/APIs. While I agree that the current implementation may not fully align with Qwik's vision, the UX issues in scroll restoration mentioned in the original post should still be fixed ASAP. It is not desirable and hurts adoption if this is left hanging. There might be some clever tricks that I'm not aware of (perhaps through some unknown internal APIs). Unfortunately, I've decided to move on from this. For the hard refresh issue specifically, it may not be that big of a concern after all. Since Qwik embraces and optimizes for MPA more than most JS frameworks (except Astro), maybe triggering a hard page refresh on Qwik has introduced so many innovative solutions to improve the initial page load experience, and it has so much potential IMO. I am happy to revisit it one day when it is more compatible with SPA. But until then, if someone cares enough about the SPA Scrolling UX in Qwik and has a solution that fits into Qwik's vision, please feel free to pick this up and fix it once and for all. I am closing this PR for now. Thank everyone who has put time into it. |
Hey! actually i am working on it, i think it's possible |
We will get it merged! |
Just pushed a bunch of changes! can you review and get your thoughts? @billykwok |
Do you think we could merge and iterate, seems like this PR would fix some issues + add a cool feature, what if we leave for a second PR:
|
This PR tried to do many things at the same time and it makes it very hard to merge, might be a good moment to merge and iterate |
let me try to find him in discord! |
Let's do it! merged this for the 1.2.0 window! cc @jordanw66 |
@billykwok @jordanw66 @manucorporat this is INCREDIBLE. Thank you guys so much for the contributions!! |
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@builder.io/qwik](https://qwik.builder.io/) ([source](https://togithub.com/BuilderIO/qwik)) | [`1.1.5` -> `1.2.6`](https://renovatebot.com/diffs/npm/@builder.io%2fqwik/1.1.5/1.2.6) | [![age](https://badges.renovateapi.com/packages/npm/@builder.io%2fqwik/1.2.6/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/@builder.io%2fqwik/1.2.6/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/@builder.io%2fqwik/1.2.6/compatibility-slim/1.1.5)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/@builder.io%2fqwik/1.2.6/confidence-slim/1.1.5)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>BuilderIO/qwik (@​builder.io/qwik)</summary> ### [`v1.2.6`](https://togithub.com/BuilderIO/qwik/releases/tag/v1.2.6) [Compare Source](https://togithub.com/BuilderIO/qwik/compare/v1.2.5...v1.2.6) ##### What's Changed - feat(server-functions): routeAction$ validation based on RequestEvent by [@​tzdesign](https://togithub.com/tzdesign) in [QwikDev/qwik#4727 - fix: visual cms starter by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4731 - feat: add jokes by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4734 - docs: fix example in Best Practices Guide by [@​octoper](https://togithub.com/octoper) in [QwikDev/qwik#4733 - fix: force spa-init into client symbols in dev builds by [@​jordanw66](https://togithub.com/jordanw66) in [QwikDev/qwik#4738 - fix: cli accept empty folder by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4740 - fix: configure jsx import by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4741 - chore: update deps by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4742 - fix: case for images by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4744 - 1.2.6 by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4743 ##### New Contributors - [@​octoper](https://togithub.com/octoper) made their first contribution in [QwikDev/qwik#4733 **Full Changelog**: QwikDev/qwik@v1.2.5...v1.2.6 ### [`v1.2.5`](https://togithub.com/BuilderIO/qwik/releases/tag/v1.2.5) [Compare Source](https://togithub.com/BuilderIO/qwik/compare/v1.2.4...v1.2.5) #### What's Changed - Insights by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4707 - docs(cart): remove padding-left from cart overlay by [@​gioboa](https://togithub.com/gioboa) in [QwikDev/qwik#4705 - docs: correct the capture index for qrl by [@​wtlin1228](https://togithub.com/wtlin1228) in [QwikDev/qwik#4706 - fix: add .pnpm-store to .prettierignore by [@​jordanw66](https://togithub.com/jordanw66) in [QwikDev/qwik#4710 - docs: add route handler menu + ecpsystem case studies by [@​hamatoyogi](https://togithub.com/hamatoyogi) in [QwikDev/qwik#4713 - fix(aws): bundle all without express by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4691 - fix: multiple cookies in azure by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4716 - fix: vite csr mode by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4719 - fix: clear attribute when undefined by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4721 - docs: fixed typo in labs index.mdx by [@​Craiqser](https://togithub.com/Craiqser) in [QwikDev/qwik#4573 - fix: routes plugins with tsx by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4726 - fix: update pandacss dep by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4725 - 1.2.5 by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4729 - fix(vite): \n escaping in vite plugin by [@​FlatMapIO](https://togithub.com/FlatMapIO) in [QwikDev/qwik#4730 **Full Changelog**: QwikDev/qwik@v1.2.4...v1.2.5 ### [`v1.2.4`](https://togithub.com/BuilderIO/qwik/releases/tag/v1.2.4) [Compare Source](https://togithub.com/BuilderIO/qwik/compare/v1.2.3...v1.2.4) ##### What's Changed - fix(eslint): useMethod rule for regular functions by [@​shairez](https://togithub.com/shairez) in [QwikDev/qwik#4666 - fix: typo by [@​yaikohi](https://togithub.com/yaikohi) in [QwikDev/qwik#4655 - fix: the property parameter can be symbol by [@​wtlin1228](https://togithub.com/wtlin1228) in [QwikDev/qwik#4668 - docs css: fix shop cart floating button by [@​gioboa](https://togithub.com/gioboa) in [QwikDev/qwik#4669 - shop: added colors to icons and small changes by [@​the-r3aper7](https://togithub.com/the-r3aper7) in [QwikDev/qwik#4670 - doc: optional font by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4672 - fix: image tools improvements by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4671 - perf: preload css fonts by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4673 - chore: update deps by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4674 - fix(optimizer): ssr transform for rollup by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4675 - fix: add loc to symbol manifest by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4676 - fix: add crossorigin attribute by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4677 - docs(request-handling): cookie has method by [@​tzdesign](https://togithub.com/tzdesign) in [QwikDev/qwik#4632 - feat(labs): add clustering to symbols by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4648 - fix: inlined signals in library mode by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4684 - fix: always try relative path for mapped hooks by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4686 - fix: configurable getOrigin for node servers by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4687 - fix: staticFile() api in node middleware by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4693 - fix(entry.deno.ts): fix wrong parameters by [@​arkhvoid](https://togithub.com/arkhvoid) in [QwikDev/qwik#4696 - fix: migrate to modern Deno Server by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4697 - fix: add vanilla node server by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4699 - 1.2.4 by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4690 - docs(mdx): fixed path to counter component by [@​YannickFricke](https://togithub.com/YannickFricke) in [QwikDev/qwik#4680 - chore: add aws badge by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4703 - chore: fix \n is pure text in console by [@​minsoo-web](https://togithub.com/minsoo-web) in [QwikDev/qwik#4700 - fix: PROTOCOL and HOST header are case insensitive by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4704 ##### New Contributors - [@​yaikohi](https://togithub.com/yaikohi) made their first contribution in [QwikDev/qwik#4655 - [@​tzdesign](https://togithub.com/tzdesign) made their first contribution in [QwikDev/qwik#4632 - [@​arkhvoid](https://togithub.com/arkhvoid) made their first contribution in [QwikDev/qwik#4696 - [@​YannickFricke](https://togithub.com/YannickFricke) made their first contribution in [QwikDev/qwik#4680 - [@​minsoo-web](https://togithub.com/minsoo-web) made their first contribution in [QwikDev/qwik#4700 **Full Changelog**: QwikDev/qwik@v1.2.3...v1.2.4 ### [`v1.2.3`](https://togithub.com/BuilderIO/qwik/releases/tag/v1.2.3) [Compare Source](https://togithub.com/BuilderIO/qwik/compare/v1.2.2...v1.2.3) #### What's Changed - docs(utilities): adding documentation for the `new` cli command by [@​thejackshelton](https://togithub.com/thejackshelton) in [QwikDev/qwik#4649 - docs: aws lambda documentation by [@​leifermendez](https://togithub.com/leifermendez) in [QwikDev/qwik#4642 - fix: server$ error when request is closed by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4653 - docs: resumable by [@​aboudard](https://togithub.com/aboudard) in [QwikDev/qwik#2780 - fix: add dependencies to pkg by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4656 - fix: navigation crash with plugins by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4657 - fix: unit test jsx image by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4660 - docs: ecosystem improvements by [@​the-r3aper7](https://togithub.com/the-r3aper7) in [QwikDev/qwik#4659 - fix(slot): rendering variable slot projection by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4661 - fix: svg rendering + test by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4663 - 1.2.3 by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4662 #### New Contributors - [@​aboudard](https://togithub.com/aboudard) made their first contribution in [QwikDev/qwik#2780 **Full Changelog**: QwikDev/qwik@v1.2.2...v1.2.3 ### [`v1.2.2`](https://togithub.com/BuilderIO/qwik/releases/tag/v1.2.2) [Compare Source](https://togithub.com/BuilderIO/qwik/compare/v1.2.1...v1.2.2) #### What's Changed - fix: csstypes dep by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4644 - feat(qwik): encode the manifest hash into the container. by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4647 **Full Changelog**: QwikDev/qwik@v1.2.1...v1.2.2 ### [`v1.2.1`](https://togithub.com/BuilderIO/qwik/releases/tag/v1.2.1) [Compare Source](https://togithub.com/BuilderIO/qwik/compare/v1.2.0...v1.2.1) #### What's Changed - docs header: add shop link by [@​gioboa](https://togithub.com/gioboa) in [QwikDev/qwik#4641 - fix: tailwind integration by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4640 **Full Changelog**: QwikDev/qwik@v1.2.0...v1.2.1 ### [`v1.2.0`](https://togithub.com/BuilderIO/qwik/releases/tag/v1.2.0) [Compare Source](https://togithub.com/BuilderIO/qwik/compare/v1.1.5...v1.2.0) ##### What's Changed - docs: fix link to `speculative-module-fetching` by [@​Craiqser](https://togithub.com/Craiqser) in [QwikDev/qwik#4421 - fix: use levenshtein distance to provide even better 404 by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4389 - feat: serialize support for Set and Map by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4375 - \[✨] Critical DX/UX improvement to SPA navigation in Qwik City by [@​billykwok](https://togithub.com/billykwok) in [QwikDev/qwik#3244 - docs: add CodeSandbox demo to Modular Forms guide by [@​fabian-hiller](https://togithub.com/fabian-hiller) in [QwikDev/qwik#4095 - docs: fix link to `Bundle Optimization` by [@​Craiqser](https://togithub.com/Craiqser) in [QwikDev/qwik#4418 - feat: image performance dev tools by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4424 - fix: slow test by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4431 - docs: qwiksand-box by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4429 - fix: image-size dep by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4435 - docs: fix example to match by [@​hamatoyogi](https://togithub.com/hamatoyogi) in [QwikDev/qwik#4439 - chore: remove unused starter file by [@​adamdbradley](https://togithub.com/adamdbradley) in [QwikDev/qwik#4446 - fix: set qwik builder counter initial value by [@​adamdbradley](https://togithub.com/adamdbradley) in [QwikDev/qwik#4449 - fix: cli background install by [@​adamdbradley](https://togithub.com/adamdbradley) in [QwikDev/qwik#4450 - feat: client info API by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4433 - fix: jsx rendering order by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4458 - Reorganize .gitignore by [@​szepeviktor](https://togithub.com/szepeviktor) in [QwikDev/qwik#4456 - docs: Routing - Change getLocation() to useLocation() by [@​chsanch](https://togithub.com/chsanch) in [QwikDev/qwik#4454 - fix: visible task execution after removal by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4459 - Fix typo in MDX example code by [@​erikras](https://togithub.com/erikras) in [QwikDev/qwik#4457 - feat(adapter): aws starter adapter by [@​leifermendez](https://togithub.com/leifermendez) in [QwikDev/qwik#4390 - fix(use-on.ts): fixed useOn methods to pass correct eventName to \_useOn by [@​OrenSayag](https://togithub.com/OrenSayag) in [QwikDev/qwik#4453 - docs: routeLoader adjustment by [@​hamatoyogi](https://togithub.com/hamatoyogi) in [QwikDev/qwik#4462 - fix: root gitignore file by [@​zanettin](https://togithub.com/zanettin) in [QwikDev/qwik#4460 - fix: add missing nonce to popstate script by [@​DustinJSilk](https://togithub.com/DustinJSilk) in [QwikDev/qwik#4468 - feat: CLI option `new` by [@​zanettin](https://togithub.com/zanettin) in [QwikDev/qwik#4273 - Include a woman in the "community" emoji by [@​erikras](https://togithub.com/erikras) in [QwikDev/qwik#4471 - docs: Update the middleware / endpoint documentation by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4442 - fix: prefetch urls with different search queries by [@​DustinJSilk](https://togithub.com/DustinJSilk) in [QwikDev/qwik#4474 - refactor: improve DX of "qwik new" by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4472 - fix: bundling for testing by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4475 - feat: image vite transform by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4479 - refactor: containerState for appendHeadStyle by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4478 - fix: implicitly end middleware chain on response by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4441 - refactor: visible tasks can run in parallel by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4477 - Update pages.json by [@​hexa-it](https://togithub.com/hexa-it) in [QwikDev/qwik#4473 - feat: update starter dev-tools by [@​adamdbradley](https://togithub.com/adamdbradley) in [QwikDev/qwik#4483 - perf: optimizer knows non-variadic components by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4484 - Add new documentation for deprecated features. by [@​nsdonato](https://togithub.com/nsdonato) in [QwikDev/qwik#4476 - feat: add no-unnecessary-condition eslint rule by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4485 - fix(parse-pathname): path segment encoding by [@​Varixo](https://togithub.com/Varixo) in [QwikDev/qwik#4486 - docs(\*): update contribution docs by [@​Wimpert](https://togithub.com/Wimpert) in [QwikDev/qwik#4490 - Allow replace state when navigating by [@​Wimpert](https://togithub.com/Wimpert) in [QwikDev/qwik#4488 - fix: test bundle mode by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4491 - fix: 'Numberish' type used for width/height didn't allow % by [@​KenAKAFrosty](https://togithub.com/KenAKAFrosty) in [QwikDev/qwik#4434 - fix: missing navigation update to static page by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4493 - 🦄 by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4495 - feat: add image to starter by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4497 - fix: $localize optimizer bug by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4498 - docs(adding content security policy to the advanced topics) by [@​the-zimmermann](https://togithub.com/the-zimmermann) in [QwikDev/qwik#4440 - fix: clientConn types by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4501 - Pr docs qwik city by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4494 - chore: fix dev release by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4511 - refactor: simplify new templates by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4512 - fix: cli new interactive by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4516 - feat: svg optimization with esm by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4526 - fix: spa redirects from non-pages by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4518 - docs: fix typos in Overview and State files. by [@​eecopa](https://togithub.com/eecopa) in [QwikDev/qwik#4524 - docs: fixed a typo in image link by [@​avanderpluijm](https://togithub.com/avanderpluijm) in [QwikDev/qwik#4514 - docs: fixed small typos in qwik-city documentation. by [@​VinuB-Dev](https://togithub.com/VinuB-Dev) in [QwikDev/qwik#4522 - feat: pandacss integration by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4515 - docs: added custom icons by [@​LoganAffleck](https://togithub.com/LoganAffleck) in [QwikDev/qwik#4513 - Update app.tsx in runtime-less example by [@​primeagen-rustaceans](https://togithub.com/primeagen-rustaceans) in [QwikDev/qwik#4467 - docs: fix typos by [@​enesflow](https://togithub.com/enesflow) in [QwikDev/qwik#4500 - docs: move think-qwik page to concepts route by [@​moinulmoin](https://togithub.com/moinulmoin) in [QwikDev/qwik#4499 - feat: frame-perfect and state-backed durable SPA scroll restoration by [@​jordanw66](https://togithub.com/jordanw66) in [QwikDev/qwik#4509 - docs: fixed typos in comments and docs by [@​ehrencrona](https://togithub.com/ehrencrona) in [QwikDev/qwik#4430 - doc: add redirect to new think-qwik docs by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4533 - fix: missing component in layout by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4535 - fix(router): use encodeURI instead by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4534 - fix: click to component for svg by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4537 - fix: regression when navigating to / by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4538 - fix: save scrollState on visibilitychange by [@​jordanw66](https://togithub.com/jordanw66) in [QwikDev/qwik#4536 - feat: automatically set qwik icons by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4539 - fix: renderToString mode is always ignored and returns an empty page by [@​ncharalampidis](https://togithub.com/ncharalampidis) in [QwikDev/qwik#4528 - fix: image?jsx strip export default by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4541 - fix(router): redirect handling by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4543 - chore: update deps by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4540 - chore: create `@builder.io/qwik-labs` by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4545 - perf: leverage modulepreload for common chunks by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4546 - fix: perfect hash scroll by [@​jordanw66](https://togithub.com/jordanw66) in [QwikDev/qwik#4550 - perf: enable navigationPreload by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4548 - Sidebar style by [@​LoganAffleck](https://togithub.com/LoganAffleck) in [QwikDev/qwik#4554 - fix: QwikIntrinsicElements does not include ref by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4555 - docs: add panda css by [@​anubra266](https://togithub.com/anubra266) in [QwikDev/qwik#4544 - feat(insights): create a new insights application by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4547 - docs: add ss-link to showcase by [@​Leizhenpeng](https://togithub.com/Leizhenpeng) in [QwikDev/qwik#2689 - fix: navigationPreload waitUntil by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4561 - feat: layout shift detection by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4560 - docs: add resource + fix css by [@​hamatoyogi](https://togithub.com/hamatoyogi) in [QwikDev/qwik#4562 - fix(qwik-city buildtime): make generated file ids unique by [@​hbendev](https://togithub.com/hbendev) in [QwikDev/qwik#4564 - feat: transform compiler architecture by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4566 - feat(insights): basic UI for seeing symbols by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4565 - docs: Add Qwik Labs section by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4568 - chore: fix broken lock file by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4574 - fix: route new template by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4576 - docs(qwik-labs edit link route): fixed qwik labs "edit page" link & so… by [@​thejackshelton](https://togithub.com/thejackshelton) in [QwikDev/qwik#4571 - feat(labs): typed routes by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4580 - docs(labs): add typed routes by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4582 - chore: fix saving of artifacts to build by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4583 - chore(labs): fix distribution build by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4584 - Internal renaming suggestions by [@​shairez](https://togithub.com/shairez) in [QwikDev/qwik#4581 - fix(labs): encodeencodeURIComponent for params by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4587 - feat: panda css use vite-macro plugin by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4588 - Qwik shop 🎁 by [@​gioboa](https://togithub.com/gioboa) in [QwikDev/qwik#4225 - fix: shop cache by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4590 - docs(advanced & concepts docs improvements): clarity / structure changes by [@​thejackshelton](https://togithub.com/thejackshelton) in [QwikDev/qwik#4592 - Add replaceState to link component by [@​Wimpert](https://togithub.com/Wimpert) in [QwikDev/qwik#4492 - docs: simplify menu by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4593 - fix: improve pandacss integration by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4594 - fix: default prettier format for starters by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4595 - chore(labs): copy build artifacts into the build git repo by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4589 - chore: update deps by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4597 - docs: fix insights docs by [@​gioboa](https://togithub.com/gioboa) in [QwikDev/qwik#4598 - chore(labs): include package.json in full build by [@​mhevery](https://togithub.com/mhevery) in [QwikDev/qwik#4599 - docs: Dynamic og image implementation by [@​mrhoodz](https://togithub.com/mrhoodz) in [QwikDev/qwik#4579 - fix: correct documentation URLs for rules created by ESLintUtils.RuleCreator by [@​wtlin1228](https://togithub.com/wtlin1228) in [QwikDev/qwik#4604 - feat: bulletproof SPA recovery by [@​jordanw66](https://togithub.com/jordanw66) in [QwikDev/qwik#4558 - fix: Social and Vendor are production only components by [@​wtlin1228](https://togithub.com/wtlin1228) in [QwikDev/qwik#4610 - docs: image optimization by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4608 - chore: change useStore link by [@​GustavoMelloGit](https://togithub.com/GustavoMelloGit) in [QwikDev/qwik#4601 - fix(qwik-core): add types for the style attribute by [@​hbendev](https://togithub.com/hbendev) in [QwikDev/qwik#4577 - docs: Update deprecation information about the basePathname by [@​julianobrasil](https://togithub.com/julianobrasil) in [QwikDev/qwik#4437 - docs: fix typos on Qwik City home by [@​corydeppen](https://togithub.com/corydeppen) in [QwikDev/qwik#4602 - feat: improve error message for duplicated loaders by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4619 - docs: dynamic ogImage feature url format fix and clean up by [@​mrhoodz](https://togithub.com/mrhoodz) in [QwikDev/qwik#4617 - fix: detect invalid html by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4623 - 1.2.0 by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4600 - fix: image devtools by [@​manucorporat](https://togithub.com/manucorporat) in [QwikDev/qwik#4626 - feat: qwik add builder.io by [@​adamdbradley](https://togithub.com/adamdbradley) in [QwikDev/qwik#4627 - feat: scroll opt-out on nav() and Link by [@​jordanw66](https://togithub.com/jordanw66) in [QwikDev/qwik#4622 ##### New Contributors - [@​erikras](https://togithub.com/erikras) made their first contribution in [QwikDev/qwik#4457 - [@​OrenSayag](https://togithub.com/OrenSayag) made their first contribution in [QwikDev/qwik#4453 - [@​hexa-it](https://togithub.com/hexa-it) made their first contribution in [QwikDev/qwik#4473 - [@​the-zimmermann](https://togithub.com/the-zimmermann) made their first contribution in [QwikDev/qwik#4440 - [@​eecopa](https://togithub.com/eecopa) made their first contribution in [QwikDev/qwik#4524 - [@​avanderpluijm](https://togithub.com/avanderpluijm) made their first contribution in [QwikDev/qwik#4514 - [@​VinuB-Dev](https://togithub.com/VinuB-Dev) made their first contribution in [QwikDev/qwik#4522 - [@​LoganAffleck](https://togithub.com/LoganAffleck) made their first contribution in [QwikDev/qwik#4513 - [@​primeagen-rustaceans](https://togithub.com/primeagen-rustaceans) made their first contribution in [QwikDev/qwik#4467 - [@​enesflow](https://togithub.com/enesflow) made their first contribution in [QwikDev/qwik#4500 - [@​moinulmoin](https://togithub.com/moinulmoin) made their first contribution in [QwikDev/qwik#4499 - [@​jordanw66](https://togithub.com/jordanw66) made their first contribution in [QwikDev/qwik#4509 - [@​ehrencrona](https://togithub.com/ehrencrona) made their first contribution in [QwikDev/qwik#4430 - [@​ncharalampidis](https://togithub.com/ncharalampidis) made their first contribution in [QwikDev/qwik#4528 - [@​anubra266](https://togithub.com/anubra266) made their first contribution in [QwikDev/qwik#4544 - [@​Leizhenpeng](https://togithub.com/Leizhenpeng) made their first contribution in [QwikDev/qwik#2689 - [@​mrhoodz](https://togithub.com/mrhoodz) made their first contribution in [QwikDev/qwik#4579 - [@​corydeppen](https://togithub.com/corydeppen) made their first contribution in [QwikDev/qwik#4602 **Full Changelog**: QwikDev/qwik@v1.1.5...v1.2.0 </details> --- ### Configuration 📅 **Schedule**: Branch creation - "after 9pm on sunday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/ascorbic/unpic-img). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi41LjMiLCJ1cGRhdGVkSW5WZXIiOiIzNi41LjMiLCJ0YXJnZXRCcmFuY2giOiJtYWluIn0=-->
What is it?
Overview
This is a relatively straightforward change that addresses a number of interrelated issues around SPA navigation in Qwik City. Some are already mentioned in other issues (#2162, #2050, #3149, #2202, #2203), while some are newly reported here.
Support MPA-like and customizable scroll restoration in SPA
Before: Qwik City always scrolls to the top upon SPA navigation, unless there is a hash segment in the URL. This is not consistent with how browsers handle MPA scroll restoration on
popstate
and creates bad UX when users return to a page with a resetted scroll position. Moreover, the behavior is hard-coded into the Qwik City navigation logic, even though different applications have their own needs (e.g. app-like and page-like UIs should restore scroll positions differently).After: The default behavior now mimics how browsers handle scroll restoration in MPA - scroll to the top for new pages (e.g.
<Link />
), but to the last-visited scroll position forpopstate
navigation (e.g. back/next button). Moreover, users can customize scroll restoration with the built-in scroll restorertoTopAlways
andtoLastPositionOnPopState
or even their own implementation. The 'before' behavior is equivalent totoTopAlways
.Race condition when restoring scroll positions
Before: Scroll position is restored after the DOM is 'settled' in order to synchronize content update and scroll position update. However, the current implementation relies on a series of hard-coded
setTimeout()
, which very often results in either early scrolling or late scrolling.After: 'DOM Settled' is accurately detected using
useLocation()
anduseVisibleTask$()
. Scroll and content updates are now always in-sync.Prevent full-page reload when
popstate
happens before manual navigationBefore: Qwik City registers a temporary
popstate
event listener to reload the page if there is anypopstate
navigation before the firstpushState
is called. This essentially turns all SPAs into MPA whenever users refresh the page. This also makes page navigation inconsistent before and after the firstpushState
. In addition, there are unnecessarypopstate
listener registration/unregistration, because the temporary listener will be replaced by a real listener anyway after the firstpushState
.After: Instead of a temporary
popstate
listener that does full-page refreshes, Qwik City now directly sets up the realpopstate
listener that updates the page without full-page refreshes.'popstate'
possible.Improve hash navigations
Before: Hash navigation is neither updating the URL hash nor written into the session history. The 'hashchange' event is also never fired.
After: The new behavior now mimics native behavior - clicking
<a href="#some-hash" />
now updates the page URL hash without triggering unnecessary re-rendering. It also gets written into session history like what browsers would natively do. The 'hashchange' event is also fired.Backward-compatible API Changes
Demo
Scroll restoration after
popstate
Before the change:
CleanShot.2023-03-18.at.01.07.05.mp4
After the change:
CleanShot.2023-03-18.at.00.57.29.mp4
popstate
after reloadBefore the change:
CleanShot.2023-03-18.at.01.07.49.mp4
After the change:
CleanShot.2023-03-18.at.01.38.36.mp4
Checklist