Skip to content
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

Default mode to history in vue-router #40

Closed
wants to merge 3 commits into from

Conversation

AVGP
Copy link

@AVGP AVGP commented May 25, 2019

Fragment URLs (aka hash URLs) are not supported well in many crawlers (such as search engine crawlers). Other frameworks have made the history API mode the default but for compatibility reasons vue-router hasn't yet. I think we can get a working solution for older browsers, modern browsers and crawlers alike with the history API or something similar, effectively reducing the risk for web developers ending up with undiscoverable websites.

Rendered

@posva posva added breaking change This RFC contains breaking changes or deprecations of old API. router labels May 25, 2019
@posva posva changed the title RFC for default History API in vue-router Defaulting mode to history in vue-router May 25, 2019
@posva posva changed the title Defaulting mode to history in vue-router Default mode to history in vue-router May 27, 2019
@Akryum
Copy link
Member

Akryum commented May 27, 2019

I'm not sure it's a good idea, since history mode requires server-side configuration to work.

@posva
Copy link
Member

posva commented May 27, 2019

I think that's okay, we should make it clearer in the guide very early by saying that you need to configure your server (with a link to a page of the docs), and on the Side navigation have a section Deployment.
People will see the problem very quickly and being able to find the problem on the docs quickly is going to be less frustrating that having SEO problems by default

@Akryum
Copy link
Member

Akryum commented May 27, 2019

Still, I think it will make learning vue-router harder. More gotchas, more issues to find solutions for. The defaults should work for everyone.

@Akryum
Copy link
Member

Akryum commented May 27, 2019

The downsides of having history as default are much more numerous and impactful than the downsides of hash as default (it doesn't look nice).

@phanan
Copy link
Member

phanan commented May 27, 2019

I'm with @Akryum on this one. The default option should be the one that works out of the box, without any extra configuration. Having history mode as the default would force the users to configure a server, which might be more troublesome than we think. In other words, history mode is a more advanced feature and should be opt-in, not opt-out.

@posva
Copy link
Member

posva commented May 27, 2019

But wait, this is not about aesthetic with the url, it's about crawlers.
About vue router being harder to learn for newcomers, I disagree, when I teach Vue router, they wonder why the URL has a hash and don't really care about IE < 10 which is the only major browser that needs that support.

The other browser needing support is Opera Mini but that is different as its objective is not to be up to date with everything
Also, keep in mind it will still work for both browsers, links would reload the page, which is acceptable in a browser like Opera Mini

and to be clear, the point here is that the hash mode does not work without extra configuration for crawlers as it would for a history mode and it's pretty much being deprecated (as I understand)

@Akryum
Copy link
Member

Akryum commented May 27, 2019

You still need to configure your server to support history mode, but hash mode just works with literally everything.

@dwsmart
Copy link

dwsmart commented May 27, 2019

@Akryum but # doesn't just work with literally everything, all the major search engines struggle crawling, and therefore ranking # URLs, along with social media sharing.

Presumably a large amount of sites care about discovery, it being an important part of their overall product.

If you concider the realtionship to be between just the user & site, then your hashtag argument has merit, but if you concider a wider picture of being search / share ready, the history mode has clear benefits, despite the drawback of server configuration needed.

@phanan
Copy link
Member

phanan commented May 27, 2019

@dwsmart If a user considers SEO, they can switch the setting and configure the server(s) instead. Now it's an opt-in feature and they should be well-prepared for all the burdens that come with it.

@ulissepress
Copy link

You still need to configure your server to support history mode, but hash mode just works with literally everything.

I agree. The default option should work for everyone without requiring complicated server-side configuration (especially when you can't configure the server, like deploying the app in GitHub or similar)

@Akryum
Copy link
Member

Akryum commented May 27, 2019

Consider this example:

(History mode is the default)
Someone new to vue-router just installs it, want to write a nice little app, publishes on her server, and then the site breaks. Then she loses 1 hour finding why and then another two hours trying to understand how to configure her server. This is not a good developer experience.

(Hash is the default)
She deploys and then the site works! Yay! Now she can continue learning. (And eventually come to history mode, its benefits and drawbacks.)

@Akryum
Copy link
Member

Akryum commented May 27, 2019

But wait, this is not about aesthetic with the url, it's about crawlers.

Is the person learning vue-router more interested in SEO or in her site working correctly?

@dwsmart
Copy link

dwsmart commented May 27, 2019

more interested in SEO or in her site working correctly?

Are the two totally exclusive? The vast majority of public facing apps would count discoverability as part of the spec for working correctly, beyond loading in the browser.

@donnysim
Copy link

I'm basing this on my first experience with angular 1 (first SPA'ish app ever), but I'd keep the default as hash. When I started with angular, the router had hash by default and it was all fine until close to project release, which then the SEO question popped. Because the default was hash, it was pretty easy to find a solution how to get rid of the hash (though it still took me some time), which is why I assume is the opposite with history - it would've taken me some time to figure out "why my site returns 404 when refreshing the page" (the info was pretty scarce back then) just when you start out with the framework/router.

Honestly, we have a lot of backend (behind login apps, don't care about SEO) that run on hash mode even if it would be pretty easy to get history mode working, just because it avoids some regex patterns and proxies in backend router.

@Akryum
Copy link
Member

Akryum commented May 27, 2019

The vast majority of public facing apps would count discoverability as part of the spec for working correctly, beyond loading in the browser.

But if it doesn't load at all, SEO doesn't even matter.

@casey6
Copy link

casey6 commented May 27, 2019

The default doesn’t need to be the best option, or even the recommended option. It just needs to work. History mode doesn’t without server configuration.

@donnysim
Copy link

About explaining, it basically boils down to: would you rather explain why there's a hash in the url, or would you rather explain how to configure their server (or why it doesn't work because you didn't mention it) based on what they use and at the end add "or you could use hash mode which works by default"? 🙂

@OnyekaIjeh
Copy link

Why make a default for a frontend framework require server tinkering?

@Justineo
Copy link
Member

Changing the default setting would be rather trivial for those who want history mode, while hash mode requires minimal background knowledge from beginners and makes the router works out-of-the-box. I don’t support this change as progressiveness is one of the core values of Vue.

@kytosai
Copy link

kytosai commented May 28, 2019

Consider this example:

(History mode is the default)
Someone new to vue-router just installs it, want to write a nice little app, publishes on her server, and then the site breaks. Then she loses 1 hour finding why and then another two hours trying to understand how to configure her server. This is not a good developer experience.

(Hash is the default)
She deploys and then the site works! Yay! Now she can continue learning. (And eventually come to history mode, its benefits and drawbacks.)

I agree with this view

Because when I started with vue-my router got the problem you just mentioned

I think to have hash mode as default is reasonable. It is great for first time vue-router users

@Jinjiang
Copy link
Member

How about just add a SEO optimization part in our guide instead? I also prefer hash mode as default. 😅
Thanks.

@AVGP
Copy link
Author

AVGP commented May 28, 2019

I see the point about server configuration. What makes me a little nervous is that it sounds like discoverability is considered optional, when I see questions about this coming up over and over again on a daily basis and a bunch of companies still shying away from JavaScript and frontend frameworks precisely because discoverability is not an afterthought or optimisation.

What I wonder is: What is the server configuration people use for local development and what is a popular deployment option? Angular and React would have the same problem as they are shipping HTML5 mode (history mode) by default but it doesn't seem to be a problem there?

I have been teaching web development for many years and since I am teaching SPAs, I do teach minimal server configuration or mention solid hosting options along.

If it does pose a significant hurdle for beginners, I would at least like to see tutorials / quick-start guides and CLI templates mention the fact that hash-URLs are an issue with crawlers and discoverability (SEO) and give the user the option than silently assuming everything will be fine with hash-URLs which it isn't. Solving this with documentation alone keeps being only mildly successful.

Example (with hash mode): A startup / company / organisation publishes their site built with Vue.js after it works fine locally and on deployment. The new website tanks in page views and organic search traffic. It is unclear why and people using other frameworks do not see similar results.

Example (with history mode): After setting up the server to serve URLs the way HTTP always worked (the server needs to know how to serve URLs), it works fine and traffic from organic search engines doesn't disappear.

@phanan
Copy link
Member

phanan commented May 28, 2019

What makes me a little nervous is that it sounds like discoverability is considered optional

Because it is optional. Just because you see many questions on the topic doesn't mean 100% of the applications that use vue-router require discoverability – there are e.g. internal applications that don't, or those that simply don't need to care. The apps that require discoverability/SEO will always be a subset (with unknown percentage, because "many" is subjective and without numbers to back up) of the total number of apps.

Having a working version right from the start, on the other hand, is not optional, and hash mode does just that.

@AVGP
Copy link
Author

AVGP commented May 28, 2019

@phanan Fair point wrt internal / login-protected sites.
But as @dwsmart just as many are public-facing sites which consider discoverability as part of the definition of "working".

Now, @casey6's point resonates with me. But could we come up with a way of making the tradeoff that is the router mode more visible to the users? Because the "hash just works :)" isn't the full picture either and just adding something to the docs isn't the best option to make people aware.

@phanan
Copy link
Member

phanan commented May 28, 2019

I believe the point here has never been "hash just works," but "hash just works as the default / from the start" 🙂. I'm all for making history mode more prominent in the doc and would even go to the extent of having a notice/warning in the hash mode doc saying it's not recommended if discoverability is a requirement.

@AVGP
Copy link
Author

AVGP commented May 28, 2019

Gotcha. So would you be comfortable with having that option / notice / warning as part of the vue-cli and the templates maybe?

@Justineo
Copy link
Member

image

Vue CLI is already using history mode as the default option (with warnings about server setup) if you choose to include Vue Router upon scaffolding. In this way, we can make users think twice about discoverability for formal projects and still make Vue Router easy to start with. Maybe we can improve our warning by addressing the benefits of history mode instead of only talking about the downside.

@posva
Copy link
Member

posva commented May 28, 2019

It seems a lot of people prefer to use the hash as a default for learning purposes and prototyping. That's fine, but in that case, we should also teach it shouldn't be used in production (except in very specific cases) as that's what I understood by talking with @AVGP . And in that case, we could also argue about why are we teaching it in the first place, even if it takes less time to teach, should we teach the right way which is history mode.

We also have some alternatives:

  1. Keep hash as a default and use it in the Getting Started docs
  • Point out very clearly that hash mode is a bad choice for SEO
  • Add a page dedicated to explaining the pros/cons behind each history mode and recommend using history with a link to the page about how to configure the server with as many different versions as possible (like CRA although it could be centralized in a single website as it is common to any SPA).
  1. Warn the user when they use the hash history (can be silenced)
  2. Make mode non optional, forcing users to be aware of the option and allowing us to quickly point it out in the docs as well without spending too much time initially explaining it

The CLI message should also be adapted to briefly describe the pros and cons of history and hash mode. Maybe with a choice list we can add more text

@Akryum
Copy link
Member

Akryum commented May 28, 2019

also teach it shouldn't be used in production

That's not true for a lot of apps, like for example login-protected or internal ones. At work we are using hash mode in production and it's perfectly fine. For us it's purely an aesthetic benefit to use history mode. Not all apps requires SEO related to vue-router.

it shouldn't be used in production if the app has SEO requirements is different than it shouldn't be used in production for any app

Keep hash as a default

Yes!

Point out very clearly that hash mode is a bad choice for SEO

Also yes! But it's not a bad choice by itself.

  1. Warn the user when they use the hash history (can be silenced)

I'm against this. I feel we just need to improve documentation for people who hare SEO requirements. Don't bloat the development experience for everyone else.

  1. Make mode non optional

I don't know, it would imply forcing new users to make the choice much sooner before we actually have time to properly teach each mode. More JS fatigue!

Maybe with a choice list we can add more text

Why not.

@EduardDopler
Copy link

I simply cannot believe that this little bit of extra configuration needed is considered so cumbersome that we - as developers - would sacrifice something extremely important like SEO optimization.
With Lighthouse and similar tools becoming de facto standards for all public-facing web apps, we would decrease ours apps' scores/quality by default.

As already stated above by others, other frameworks made the same switch - without leaving novice developers behind.

All servers I worked with needed 1-3 extra lines of configuration. This is a copy-and-paste thing.

I see the hash-based method as a total hack. And a professional framework-tool like vue-router shouldn't be promoting hacks but The Best Way™️, even if that means one has to RTFM.

@posva
Copy link
Member

posva commented May 29, 2019

That's not true for a lot of apps, (...). Not all apps requires SEO related to vue-router.

That's why I said shouldn't and added (except in very specific cases). The fact is hash is a hack that became obsolete with HTML5 history API, it has the advantage of handling direct navigation without server config, that's true. My point here is that we should teach why it isn't good, say some examples about valid use cases for the hash mode and let people decide if they should use history or not. We need to make clear that general user-facing apps should never be using hash mode because of the SEO reasons mentioned on the RFC

@Akryum
Copy link
Member

Akryum commented May 29, 2019

(except in very specific cases)

Those are not very specific cases.

@AleksejDix
Copy link

AleksejDix commented May 31, 2019

I will give my 2 cents to this discussion.
I like the proposed change and I will explain why.
During my daily job, I'm focused on building internal Company Dashboards for working with Clients Data. A Very common request is that we have a Requirement like this When I click a link I want to jump to Specific Part of a Page for better sharing. That's why we always use history as a default mode for Vue Router

Imagine you have to implement this logic.

internal.customer.com/#/id/#jump-to-link

This would be impossible to implement without fiddling around.
Developers are basically forced to implement a default browser behavior in a new way and this costs much more time than configuring the server.

A perfect example would be the Heading Implementation on the github.com readme pages, People can always share a subsection of the page without any trouble.

@filrak
Copy link

filrak commented Jun 8, 2019

Imho as mamy before me pointed out - default configuration should work for everyone.

We can't forget SEO diecoverability is just one of the use cases (as said before) that is not necesarly valid for dashboards and closed company software so changing defaults to one that don't work for everyone to fulfill just some of the use cases doesn't sound like a good idea.

It should be docs resposibility to promote good practices that require a little bit more from the developer. There are many ways to encourage people to use history mode (like including information about setting it as installation step with proper warnings and links to pros/cons as @posva suggested).

Also changing this default could be confusing for mamy newcomers reading old tutorials/videos since history mode setting is included almost everywhere

@posva
Copy link
Member

posva commented Jun 8, 2019

Also changing this default could be confusing for mamy newcomers reading old tutorials/videos since history mode setting is included almost everywhere

The mode will certainly not be a string anymore in future versions to allow custom implementations

@jonaskuske
Copy link

jonaskuske commented Jun 9, 2019

Those are not very specific cases.

The web has a well-defined way of specifying locations and publicly exposing them and that is URIs.
Abusing them in a way that breaks both server-side access and the default behavior of fragments is a hack.

Internal/non-public tools, which there are indeed many of, can get away with this hack – and they're "specific" cases not because they're incredibly rare, but because they don't follow the "default mode" of the web (public content), and thus decide against using normal URIs. This decision should be an active choice and not the silent default. (and yes, websites and webapps being publicly accessible in some form is definitely the default imo)

So I think that either history needs to become default or the Router should simply not have a default and require an active choice.

@smolinari
Copy link
Contributor

smolinari commented Jun 9, 2019

From my understanding, this needs to be looked at from two different perspectives: the development server perspective and the production server perspective. From a development server (webpack) perspective, it isn't necessary to have history mode on, except maybe for IE <10, and that MUST be a very small minority of developers needing it. Thus, it's not really a reason for hashed URLs. And saying "but with hash-mode, it works for everyone" isn't a reason either.

The fact Vue CLI is THE "better way" and for most the preferred way to develop Vue applications means having Vue Router work with Webpack in the history mode should be a given, the default.

As for the production side of the coin, this is where documentation needs to come in. It would need to be clear that "continuing" the history/ non-hashed mode into production would require server configuration (setting up redirects). If the server can't be configured for redirects (which the majority certainly can), then the hash mode would need to be set, which should only be in rare cases (not the norm).

To me, it makes sense to have the history mode be the default mode, simply because it's how the web works. It's the norm. Doing things against that norm means the way it works (hashed mode) is not normal. Being "not normal" is not Vue-like. 😁

My 2 cents.

Scott

@UltraCakeBakery
Copy link

We should change the default and not care about the "I'm too lazy to read the docs. I use stack overflow and YouTube for all my answers. Why doesn't my app work?" people that need 10+ minutes to configure their servers to work with SPA.

There is no excuse except bad planning for anyone to have trouble with this change.

@michaeldrotar
Copy link

I was of the opinion that of course it should be history.. after reading everything, I started to agree with the arguments to keep it as hash.

But I have a question.. since I've never used hash mode and I didn't see it mentioned.. what happens when you need an actual anchor in a document?

  • Does the hash mode do some shenanigans to have another anchor prop and to scroll the document to it so it works as expected?
  • Does it get ignored?
  • Does it break cause default browser behavior replaces the hash path with the anchor and vue-router understandably can't find a route with the new value? (yikes)

@posva
Copy link
Member

posva commented Feb 28, 2020

@AVGP Thanks a lot for this Martin. It was very valuable to gather feedback around this.
For the next iteration of vue-router (https://github.com/vuejs/vue-router-next) we have to explicitly pass the history implementation. This improves the size of the bundle and allows us to take a different approach when documenting the router usage:

const router = createRouter({
  history: createWebHashHistory(),
  // ...
})

I think we can still show the examples using the Hash history so new users reading the docs do not need to setup anything server side to make their app work when deployed, but it makes it more likely for users to check what is that history option is and check the detailed information in the docs.

@AVGP
Copy link
Author

AVGP commented Feb 28, 2020

Thanks for the update, @posva. If I'm not mistaken, the CLI defaults to history mode right now, which is great, too :)

@posva
Copy link
Member

posva commented Feb 28, 2020

That's true! Let's close this RFC then. Thank you again @AVGP 🙂

@posva posva closed this Feb 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change This RFC contains breaking changes or deprecations of old API. router
Projects
None yet
Development

Successfully merging this pull request may close these issues.