Skip to content

Add Navigation API example#1876

Open
Master-Hash wants to merge 23 commits intowakujs:mainfrom
Master-Hash:navigation-api-example
Open

Add Navigation API example#1876
Master-Hash wants to merge 23 commits intowakujs:mainfrom
Master-Hash:navigation-api-example

Conversation

@Master-Hash
Copy link
Contributor

@Master-Hash Master-Hash commented Dec 26, 2025

Current it lacks:

  • full clean up
  • control scroll, startTransition, etc on <Link> component basis1

Footnotes

  1. It is automatically by default; set scroll: "manual" and handle every scroll is the only way to adjust scroll behavior on <Link> component basis, but now it's buggy; currently Firefox's behavior is inconsistent and buggy

@vercel
Copy link

vercel bot commented Dec 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
waku Ready Ready Preview Feb 19, 2026 10:44am

Request Review

@codesandbox-ci
Copy link

codesandbox-ci bot commented Dec 26, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked the MyRouter code, but it feels like a great start.
I assume it's still work in progress, and convert to draft for now.

@dai-shi dai-shi marked this pull request as draft December 27, 2025 00:44
@dai-shi
Copy link
Member

dai-shi commented Dec 27, 2025

examples/5* is for minimal api, so this is probably better for 46_ or even 61_. By the way, we plan to separate examples repo in the future.

Master-Hash

This comment was marked as duplicate.

Comment on lines +875 to +912
useEffect(() => {
const callback = (path: string, query: string) => {
const fn = () => {
const url = new URL(window.location.href);
url.pathname = path;
url.search = query;
url.hash = '';
changeRoute(parseRoute(url), {
skipRefetch: true,
shouldScroll: false,
})
.catch((err) => {
console.log('Error while handling location listeners:', err);
})
.finally(() => {
if (path !== '/404') {
window.history.pushState(
{
...window.history.state,
waku_new_path: url.pathname !== window.location.pathname,
},
'',
url,
);
}
});
};
if (refetching.current) {
refetching.current.push(fn);
} else {
startTransition(fn);
}
};
locationListeners.add(callback);
return () => {
locationListeners.delete(callback);
};
}, [changeRoute, locationListeners]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand this locationListeners. From commit history this is a workaround, but how?

(sorry for too many notification, github ui sucks)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR, this was introduced so that we changeRoute synchronously with other React rendering. We should probably create an e2e test case that covers it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create an e2e test case that covers it.

Any existing example?

btw I'll left the history here. I don't know how to convert this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create an e2e test case that covers it.

Any existing example?

Actually, there seems some e2e tests fail if we comment out locationListeners.add(callback);.

@Master-Hash
Copy link
Contributor Author

Master-Hash commented Dec 27, 2025

I haven't looked the MyRouter code, but it feels like a great start. I assume it's still work in progress, and convert to draft for now.

It's now a working demo, and maybe you have better intuition about cleaning up, or if lacking what is tolerable. So look forward to you reviewing opinion!

@Master-Hash
Copy link
Contributor Author

Master-Hash commented Dec 28, 2025

I want to make startTransition integrated and compulsory, but API change is out of scoop of the pr.

It should be ready now.

I somehow managed to test it on Chrome.

@Master-Hash Master-Hash requested a review from dai-shi December 28, 2025 09:37
@Master-Hash Master-Hash marked this pull request as ready for review December 28, 2025 09:37
Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the goal of this PR is to keep the current Router API surface, it looks like a minimal change, and should be good even though I didn't have closer look around navigation api.
The copy-pasted code isn't really comfortable, so I'll create a follow-up PR to expose some internal utils/types with unstable prefix. (In the long term, I guess this might not be kept.)

Our current Router with history api still has some issues, and we'll fix them, but I'll keep in mind for the navigation api.

@Master-Hash
Copy link
Contributor Author

If the goal of this PR is to keep the current Router API surface

Yes.

The copy-pasted code isn't really comfortable, so I'll create a follow-up PR to expose some internal utils/types with unstable prefix. (In the long term, I guess this might not be kept.)

You said "I don't want to mix", do you have a re-consideration?

unstable_api is favourable than a copy-paste version for me. Still, a working playground is valuable as a base for further API change, etc.

@dai-shi
Copy link
Member

dai-shi commented Dec 29, 2025

Yes. I don't want to mix. I'll see what I'm comfortable with. This PR should go as-is.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 29, 2025

Open in StackBlitz

npm i https://pkg.pr.new/wakujs/waku@1876

commit: 21c0657

@Master-Hash Master-Hash force-pushed the navigation-api-example branch from b059ccb to e8349aa Compare December 29, 2025 12:44
@Master-Hash
Copy link
Contributor Author

Playwright WebKit version is 26.0. It supports Navigation API since 26.2.

Copy-paste creates some type error, which is hard to fix. (Maybe // @ts-nocheck ?)

False positive is annoying.

@dai-shi
Copy link
Member

dai-shi commented Dec 29, 2025

some type error

Add @ts-expect-error and FIXME. I'll check afterwards.

Playwright WebKit version is 26.0. It supports Navigation API since 26.2.

Sounds like we should wait for Playwright update.

@dai-shi
Copy link
Member

dai-shi commented Dec 30, 2025

TODO:

  • Check type errors and find workarounds @dai-shi (probably a separate PR)
  • Wait for Playwright to support Navigation API

@Master-Hash
Copy link
Contributor Author

Master-Hash commented Dec 30, 2025

race condition

Buggy in extreme condition: Click two <Link> rapidly by a.click();b.click();. Potentially because of some location API not removed.

(upstream router also breaks in extreme condition.)
Uncaught (in promise) TypeError: can't access property 0, jt.current is null
    Vt https://waku.gg/assets/index-BtWEG1Tu.js:10
    Ft https://waku.gg/assets/index-BtWEG1Tu.js:10
    Vt https://waku.gg/assets/index-BtWEG1Tu.js:10
    _l https://waku.gg/assets/index-BtWEG1Tu.js:10
    Ft https://waku.gg/assets/index-BtWEG1Tu.js:10
    _l https://waku.gg/assets/index-BtWEG1Tu.js:10
    jt https://waku.gg/assets/index-BtWEG1Tu.js:10
    od https://waku.gg/assets/index-BtWEG1Tu.js:9
    Tf https://waku.gg/assets/index-BtWEG1Tu.js:9
    yo https://waku.gg/assets/index-BtWEG1Tu.js:9
    Tf https://waku.gg/assets/index-BtWEG1Tu.js:9
    Yf https://waku.gg/assets/index-BtWEG1Tu.js:10
    Nv https://waku.gg/assets/index-BtWEG1Tu.js:10
    <anonymous> debugger eval code:1
[index-BtWEG1Tu.js:10:44162](https://waku.gg/assets/index-BtWEG1Tu.js)
Uncaught Error: Minified React error #520; visit https://react.dev/errors/520 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    Bh https://waku.gg/assets/index-BtWEG1Tu.js:9
    Pu https://waku.gg/assets/index-BtWEG1Tu.js:9
    Kh https://waku.gg/assets/index-BtWEG1Tu.js:9
    Qr https://waku.gg/assets/index-BtWEG1Tu.js:9
    nd https://waku.gg/assets/index-BtWEG1Tu.js:9
    pt https://waku.gg/assets/index-BtWEG1Tu.js:2
    Ty https://waku.gg/assets/index-BtWEG1Tu.js:2
    Ty https://waku.gg/assets/index-BtWEG1Tu.js:2
    Ay https://waku.gg/assets/index-BtWEG1Tu.js:2
    zy https://waku.gg/assets/index-BtWEG1Tu.js:2
    py https://waku.gg/assets/index-BtWEG1Tu.js:10
    <anonymous> https://waku.gg/assets/index-BtWEG1Tu.js:10
Caused by: Error: Invalid element: route:/guides
    Oi https://waku.gg/assets/index-BtWEG1Tu.js:2
    zc https://waku.gg/assets/index-BtWEG1Tu.js:9
    Lc https://waku.gg/assets/index-BtWEG1Tu.js:9
    mr https://waku.gg/assets/index-BtWEG1Tu.js:9
    Kr https://waku.gg/assets/index-BtWEG1Tu.js:9
    Jh https://waku.gg/assets/index-BtWEG1Tu.js:9
    Kh https://waku.gg/assets/index-BtWEG1Tu.js:9
    Qr https://waku.gg/assets/index-BtWEG1Tu.js:9
    nd https://waku.gg/assets/index-BtWEG1Tu.js:9
    pt https://waku.gg/assets/index-BtWEG1Tu.js:2
    Ty https://waku.gg/assets/index-BtWEG1Tu.js:2
    Ty https://waku.gg/assets/index-BtWEG1Tu.js:2
    Ay https://waku.gg/assets/index-BtWEG1Tu.js:2
    zy https://waku.gg/assets/index-BtWEG1Tu.js:2
    py https://waku.gg/assets/index-BtWEG1Tu.js:10
    <anonymous> https://waku.gg/assets/index-BtWEG1Tu.js:10

@dai-shi
Copy link
Member

dai-shi commented Dec 31, 2025

Could you open a new issue for the current Router (history api based)?

Also, as I said, we have several issues in the current Router, which actually need some help. If you are interested, feel free to jump in. Like #1818, #1437, #1399.

@Master-Hash
Copy link
Contributor Author

Master-Hash commented Dec 31, 2025

Could you open a new issue for the current Router (history api based)?

Also, as I said, we have several issues in the current Router, which actually need some help. If you are interested, feel free to jump in. Like #1818, #1437, #1399.

Well, I made another branch with more thorough clean up. It will fix them all: scroll, time of changing url, race condition.

I deleted everything I don't understand. I'll see if this can pass the e2e test.

https://github.com/Master-Hash/waku/tree/rash-router

Update:
29 failed
98 skipped
236 passed (21.0m)

@Master-Hash
Copy link
Contributor Author

Master-Hash commented Jan 4, 2026

My branch has passed all e2e test!

https://github.com/Master-Hash/waku/tree/rash-router

https://github.com/Master-Hash/waku/actions/runs/20690707953/job/59398409173

I'll write up the details as soon as possible. If you like it, I'll create a draft pull request.

UPDATE: write-up

@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Jan 5, 2026

Not sure if referenced, but async-react's client router has concise comparison of history and navigation API https://github.com/rickhanlonii/async-react/blob/c971b2fa57785dc2014251ec90d3c18cb7a958c6/src/router/index.jsx For example, pendingNav within useLayoutEfffect is related to what I brought up in #1516 (comment)

@Master-Hash
Copy link
Contributor Author

Master-Hash commented Jan 5, 2026

Not sure if referenced, but async-react's client router has concise comparison of history and navigation API rickhanlonii/async-react@c971b2f/src/router/index.jsx For example, pendingNav within useLayoutEfffect is related to what I brought up in #1516 (comment)

Thank you for mention it. I believe the solution I coined is exactly the same with async-react.

@dai-shi
Copy link
Member

dai-shi commented Jan 11, 2026

UPDATE: write-up

I didn't notice this was added.

And, I misunderstood that you were solving with History API for this 👇 .

Also, as I said, we have several issues in the current Router, which actually need some help. If you are interested, feel free to jump in. Like #1818, #1437, #1399.


For Navigation API solution, feel free to update this PR. Or, maybe we can create a separate package. Which do you prefer?

In any case, I think we need to solve our current router with History API in the meantime.

@Master-Hash
Copy link
Contributor Author

For Navigation API solution, feel free to update this PR. Or, maybe we can create a separate package. Which do you prefer?

I'm using a pnpm patch on my own website.

https://github.com/Master-Hash/hashland/blob/vite/patches/waku.patch

I can keep my fork, so an official separate package isn't necessary for me.

(You can also see how Navigation API works in production on that website)

In any case, I think we need to solve our current router with History API in the meantime.

Yes, but I hate history API:(

@dai-shi
Copy link
Member

dai-shi commented Jan 11, 2026

Yes, but I hate history API:(

That's unfortunate. I don't think we can throw it away yet. Let's hope we find another contributor.

I would like to migrate to Navigation API eventually, but when I were to do it, I might reconsider some requirements. I want our client router code to be thinner. Not sure. Will see.

@Master-Hash
Copy link
Contributor Author

I want our client router code to be thinner.

I've cut it ~200 lines of code down. Now the navigation itself is optimal, network is also, only error handler (404, redirection) needs a full reconsideration.

@dai-shi
Copy link
Member

dai-shi commented Jan 11, 2026

Would you please update this PR with your latest approach? Not changing the current router, but as the 46_navigation_api example.

@dai-shi
Copy link
Member

dai-shi commented Jan 11, 2026

Or, maybe we can create a separate package.

I'll try something. This will help me understand the problem space as well as #1881.

@Master-Hash Master-Hash force-pushed the navigation-api-example branch from 39f5bea to a234600 Compare January 11, 2026 05:43
@dai-shi dai-shi changed the base branch from main to fix/router/expose-client-internals January 11, 2026 09:11
@dai-shi dai-shi deleted the branch wakujs:main January 11, 2026 13:02
@dai-shi dai-shi closed this Jan 11, 2026
@dai-shi dai-shi reopened this Jan 11, 2026
@dai-shi dai-shi changed the base branch from fix/router/expose-client-internals to main January 11, 2026 13:04
@Master-Hash
Copy link
Contributor Author

Or, maybe we can create a separate package.

I'll try something. This will help me understand the problem space as well as #1881.

Or, a new subpath? I'm in favor of this.

@dai-shi
Copy link
Member

dai-shi commented Jan 12, 2026

It doesn't happen anytime soon. By the way, when do you think we can drop history api completely? I think if we were to support navigation api, we might need to have history api fallback for quite a while. We'll probably learn from other frameworks. Until then, I would like to finish implementing the history api based router (which can then turn into a separate package in the future.)

@dai-shi
Copy link
Member

dai-shi commented Jan 12, 2026

TODO:

@Master-Hash
Copy link
Contributor Author

By the way, when do you think we can drop history api completely?

~2 years later?

@Master-Hash
Copy link
Contributor Author

Master-Hash commented Feb 19, 2026

I'll try my best to catch up with upstream client.tsx.

Some part of client.tsx is no longer needed in Navigation API, like routeChangeListeners and routeInterceptor. I'll delete them all, and keep the rest.

I also have some ideas about <NotFound> and <Redirect>. I want to upstream some recently.


It's a little tricky to use separated lib. :(

@dai-shi
Copy link
Member

dai-shi commented Feb 19, 2026

I believe unstable_routeInterceptor is not related with history api / navigation api, but to cover some edge use cases. But, you can ignore it for now.

I'll continue to work on waku-navigation later, but my current focus is fixing the history api-based router.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants