3.0.1
https://codesandbox.io/s/zlvz65rplp
Navigate to myapp.com?foo=bar
Hash is appended before query parameters, to get the final result of myapp.com/#/?foo=bar
Hash is placed after parameters myapp.com?foo=bar#/ (also making the query parameters inaccessible with this.$route.query)
Note on codesandbox link - unable to place query parameter for initial URL in editor preview - please remove /#/ & append ?foo=bar
Running across this in an instance where user authentication is done outside our app, but client/user identifier is passed to our app in query parameter upon authorization.
Next time, please take the time to complete the repro, it would have taken you 2 minutes.
@posva Would have done it if I knew how to technically make it happen with codesandbox!
Note on codesandbox link - unable to place query parameter for initial URL in editor preview - please remove /#/ & append ?foo=bar
What I meant is completing the code : adding one route, injecting the router and displaying query params.
Firgot to say, a workaround for this is setting up a route rewrite in your server
@posva Respectfully, I'm not sure we're on the same page. The only thing needed to reproduce this issue is importing vue-router & setting the correct path, which I did here:
export default new Router({
path: "/"
});
Adding anything else would be extraneous fluff.
The prominent issue here (and this is my fault for a poor title) isn't necessarily that it cannot detect the query parameters that precede the hash — the issue is that upon initially landing on an application that contains query parameters in the URL, the hash is being injected into the URL at the wrong place (after the query params instead of preceding them).
A side-effect of this is this.$route.query not being able to detect the parameters, but I'm not convinced it should. From a maintainers perspective, keep it as simple as possible, right?
I appreciate the workaround! As a matter of due diligence, I already researched this issue prior and was aware of the workaround, but going back to my original issue:
Running across this in an instance where user authentication is done outside our app, but client/user identifier is passed to our app in query parameter upon authorization.
I probably didn't make this clear enough, but in my specific case, I'm not able to control the server or the URL directing to our app - so unfortunately I cannot apply the workaround.
Edited title to better reflect core issue. I don't believe vue-router should try to support detecting query params before /#/
Respectfully, I'm not sure we're on the same page. The only thing needed to reproduce this issue is importing vue-router & setting the correct path, which I did here:
Well, for starters, since you did not actually add the router to the app in new Vue, you missed that your router config was incorrect (but unrelated) to this issue.
I fixed this for you: https://codesandbox.io/s/5wpjknyy6x
I'm also having this same issue when trying to use oauth with github. My callback url is set to https://myurl.com/#/ in github and when I get redirected it's still redirecting me to https://myurl.com?code=1234567890#/
Note that the workaround (see below) referenced in the other issue is unsatisfactory because
URLSearchParams does not have full cross-browser supportconst query = (new URLSearchParams(window.location.search.substring(1)));
if (query.has('code') && query.has('state')) {
Hey @posva,
Is it possible to get a link to the PR I brief look at outstanding PR's and could not find it, or am I misunderstanding the tag?
Cheers.
Using both the latest dev and also b7715dc a hash is still placed at the end of the URI on load, which breaks query params.
As far as I can tell this issue was not fixed.
What was the url that didn't work on the dev branch?
@posva It's not fixed on the latest dev branch for me either. The url doesn't matter, it could be anything that has a query string already in it but not a hash. ie http://example.com/?foo=bar will get turned into http://example.com/?foo=bar#/
The problem with this is that I can't ever get rid of the query string, no matter how I redirect to another route. The query string is stuck there forever in the URL.
@posva looks like dist/ was not updated, but I can't make heads or tails on how to fix that. The getURL() function in dist/vue.router.js is much older than in src/ . It might be a good idea to bump up the version number too so folk aren't wasting time in confusion.
I've forked my own version and updated dist, and it works as expected.
dist files are build on release so to test against dev you always must run yarn run build. I will roll a new version soon after writing some missing docs
Since this breaks other usages like Wordpress plugins or any other case where the server uses the query to render a different page (See https://github.com/vuejs/vue-router/issues/2876), we will have to revert this. For those still seeing the problem, there are multiple options
location.search exists and call location.replace with a version that matches your needs, eg:if (location.search) {
location.replace(location.pathname + location.hash + location.search)
}
This is a very simple version that might not fulfil every usecase, adapt it to your own needs. The function that allowed this behavior from 3.1.0 to 3.1.1 was this function:
function getUrl (path) {
const href = window.location.href
const hashPos = href.indexOf('#')
let base = hashPos > -1 ? href.slice(0, hashPos) : href
const searchPos = base.indexOf('?')
const query = searchPos > -1 ? base.slice(searchPos) : ''
base = query ? base.slice(0, searchPos) : base
return `${base}#${path + query}`
}
So you could pass the result of this function to location.replace before Vue Router starts if you need that behavior.
Since from the server perspective post?id=3 is a different url than post?=3, it makes sense to keep that with the search and treat them as different urls. Contrary to that, the hash cannot be read on the server (it is not sent alongside the request)
@posva Can this be enabled via configuration option? Not having this functionality breaks other hosting platforms like Squarespace. It causes the query string to be stuck in the URL forever because going to new routes doesn't strip them out properly. There still is an underlying bug in that case where the query string detected is everything after the FIRST ? , so I still think this will be broken if left untouched.
@posva Can you elaborate how fixing the hash placement after initial page load breaks functionality of the server reading the query strings? That happens before the DOM is loaded, Vue is mounted, etc.
I'm also facing same issue,i will keep watch it.
@posva Maybe I am missing something, and I apologize if I am, but I forked @LinusBorg 's update to the sandbox, updated the versions of Vue to 2.6.11 and Vue-Router to 3.1.5 and also added a simple computed property that gets it's value from the query param and it still appears that the # is being placed after the query params and this.$route.query.foo is undefined.
https://codesandbox.io/s/vue-template-fxmc1
Going to https://fxmc1.csb.app/?foo=123, foo is undefined and the url becomes https://fxmc1.csb.app/?foo=123#/
I would expect it should be https://fxmc1.csb.app/#/?foo=123 and foo would be 123
Is there any news?
Facing the same issue.
Maybe setting the VueRouter to history mode, but that's not satisfactory.
Thanks 🙏
Please see https://github.com/vuejs/vue-router/issues/2125#issuecomment-519521424
Most helpful comment
I'm also having this same issue when trying to use oauth with github. My callback url is set to
https://myurl.com/#/in github and when I get redirected it's still redirecting me tohttps://myurl.com?code=1234567890#/