craftedbygc / taxi

Taxi is a 🤏 small and 🐊 snappy js library for adding slick PJAX navigation and beautiful transitions to your website.
https://taxi.js.org
565 stars 11 forks source link

Using taxi.preload() sometimes causes browser to navigate to url #3

Closed andrewtraina closed 2 years ago

andrewtraina commented 2 years ago

Describe the bug

Generally, it's not well documented on how to best preload urls. Like, can I do this from within the taxi renderer onEnter() hooks? I haven't been able to reference preload anywhere except after the taxi object is instantiated.

More specifically, if the preload fetch throws an error, like 404 it's not caught and causes the browser to navigate to that url. I think minimally this is a bug that might need fixing.

Love the library, thanks for building it!

To Reproduce Steps to reproduce the behavior:

//create your taxi instance and then: taxi.preload('/foo') where /foo will resolve as 404 error, and taxi navigates the page to the URL.

Info If applicable, add screenshots to help explain your problem.

jakewhiteley commented 2 years ago

Hi @andrewtraina sorry for the late reply,

This is now fixed in v 1.0.4.

Basically, if something goes really wrong during a fetch then Taxi defaults to just loading the next URL as a fallback. For normal navigation this makes sense as we still want the user to get to where they are trying to go. But as you pointed out (sorry I missed this in the first place), this is pretty awful behaviour for a prefetch.

In 1.0.4, a failed prefetch fails gracefully, and allows you to catch the error if you wish:

taxi.preload('/path/to/404')
    .then(() => console.log('success!'))
    .catch(err => console.warn(err))

As for when to prefetch, you can do this from anywhere at any time provided you have a reference to the taxi instance. For me personally, I keep my global instances of things in a store object so that I can access object instances from any of my js files.

You could also init Taxi in a file and export that instance, meaning anywhere in your code that you imported it, it would be an instance of Taxi rather than just the class definition, and you could happily call methods :)

The one thing I avoided was making Taxi completely static/a singleton by default as I consider this to be a bit of an antipattern in js these days!

jakewhiteley commented 2 years ago

Please let me know if I missed anything, or if you have further questions!

andrewtraina commented 2 years ago

This is great, thanks so much for such a quick and thorough solution and explanation!