thepassle / app-tools

128 stars 8 forks source link

Router throws error when clicking link to custom protocol #9

Closed JudahGabriel closed 1 year ago

JudahGabriel commented 1 year ago

Custom protocols, like the ones Github uses when it tries to launch Github Desktop or VS Code, will cause the router to throw an error.

Example custom protocol:

x-github-client://openRepo/https://github.com/pwa-builder/pwabuilder-oculus

If I use App Tools Router, then have a link in my app:

<a href="x-github-client://openRepo/https://github.com/pwa-builder/pwabuilder-oculus">Open in Github Desktop</a>

Clicking on that link will cause the router to throw an error:

Uncaught (in promise) DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'http://openRepo/https://github.com/pwa-builder/pwabuilder-oculus' cannot be created in a document with origin 'http://localhost:5173' and URL 'http://localhost:5173/detail/abcxyz'. at Router.navigate (http://localhost:5173/node_modules/.vite/deps/@thepassle_app-tools_router__js.js?v=833e0bfe:186:20)

Investigating the issue, I see that it correctly identifies that the route isn't one of my app routes. However, it then checks if it matches the fallback, and it does:

// In router/index.js
async navigate(url) {
    if (typeof url === 'string') {
      url = new URL(url, this.baseUrl);
    }    

    // THIS IS THE LINE IN QUESTION:
    // The _matchRoute(url) correctly returns falsey, but _matchRoute(this.fallback) returns the fallback route.
    // A few lines later we call window.history.pushState(null, '', `${url.pathname}${url.search}`), and this fails with error.
    this.route = this._matchRoute(url) || this._matchRoute(this.fallback); 
    log(`Navigating to ${url.pathname}${url.search}`, { context: this.context, route: this.route });
}

Would you accept a PR fixing this?

thepassle commented 1 year ago

Would be happy to take a pr for this 🙂

JudahGabriel commented 1 year ago

Submitted a PR here. Thanks!