535

How can I fetch query parameters in Vue.js?

E.g.

http://somesite.com?test=yay

Can’t find a way to fetch or do I need to use pure JS or some library for this?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Rob
  • 10,851
  • 21
  • 69
  • 109
  • 21
    Why is this getting down voted? I need it for Vue.js. If there is some vue library or something built in it would be preferred over raw js. – Rob Mar 10 '16 at 10:54
  • 72
    There is not even close to a duplicate. [tag:vue.js] is a framework with a specific logic, different from vanila javascript – Yerko Palma Mar 10 '16 at 12:10
  • 27
    How can this be accomplished without vue-router? – Connor Leech Sep 29 '17 at 16:07
  • @ConnorLeech not sure why you would want to skip vue-router, since it's designed for Vue. Please use the provided API. – kissu Dec 03 '22 at 16:47

13 Answers13

716

According to the docs of route object, you have access to a $route object from your components, which exposes what you need. In this case

// from your component
console.log(this.$route.query.test) // outputs 'yay'
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Yerko Palma
  • 12,041
  • 5
  • 33
  • 57
  • 15
    Yup! If he is not using `vue-router` than this would indeed be a duplicate, as he will need to use standard JS methods. – Jeff Mar 10 '16 at 15:40
  • 1
    The problem is that the vue documentation considers coupling components to the router to be undesirable. They recommend passing props but it doesn't seem possible to pass query params dynamically as props. For example in a beforeEach guard doing something like `return next({ name: 'login', query:{param1: "foo" }, });` doesn't work. inside the login component the prop `param1` is undefined. – hraynaud Apr 07 '19 at 17:57
  • 3
    Unfortunately this only works for URL query parameters within the hash part (URL fragment), not plain old query parameters like the OP gave as example. Here's the correct answer for the OP, IMHO: https://stackoverflow.com/a/52587655/79485 – Marcel Jan 14 '21 at 14:07
  • 1
    how about in vuejs 3? – Nanda Z Feb 18 '21 at 00:44
  • -bundler.js:220 Uncaught TypeError: Cannot read properties of undefined (reading 'query') at Proxy.button_update (Update.vue:71:31) at _createElementVNode.onCl – CS QGB Apr 11 '23 at 18:22
96

Without vue-router, split the URL

var vm = new Vue({
  ....
  created() {
    let uri = window.location.href.split('?');
    if(uri.length == 2) {
      let vars = uri[1].split('&');
      let getVars = {};
      let tmp = '';
      vars.forEach(function(v) {
        tmp = v.split('=');
        if(tmp.length == 2)
          getVars[tmp[0]] = tmp[1];
      });
      console.log(getVars);
      // do 
    }
  },
  updated() {
  },
....

Another solution https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search:

var vm = new Vue({
  ....
  created() {
    let uri = window.location.search.substring(1); 
    let params = new URLSearchParams(uri);
    console.log(params.get("var_name"));
  },
  updated() {
  },
....
kissu
  • 40,416
  • 14
  • 65
  • 133
erajuan
  • 2,224
  • 20
  • 31
  • 9
    Why would you split `location.href` yourself when there is `location.search` readily available? https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search e.g. `var querypairs = window.location.search.substr(1).split('&');` Also splitting the query name-value pairs by '=' will not always work as you can pass named query parameters without value as well; e.g. `?par1=15&par2` Your code would now raise an exception on par2 as splitting by '=' will result in tmp with only 1 element. – Arthur Jan 31 '18 at 21:04
  • 3
    Sorry would not throw an exception but you would not catch par2 either. As you basically assign `undefined` to `getVars['par2']`. – Arthur Jan 31 '18 at 21:11
  • the GET method is a string (name/value pairs), in the URL – erajuan Jan 31 '18 at 23:48
  • @Arthur you are right, I added a validation and I added another solutions. thank you – erajuan Feb 01 '18 at 00:07
  • The `.substring(1)` seems to be unnecessary – Tofandel Sep 29 '20 at 19:17
  • What is the use case of avoiding router in vue? Any advantages? – nosbor Dec 12 '22 at 20:54
89

Try this code

var vm = new Vue({
  created() {
    let urlParams = new URLSearchParams(window.location.search);
    console.log(urlParams.has('yourParam')); // true
    console.log(urlParams.get('yourParam')); // "MyParam"
  },
});
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Correcter
  • 3,466
  • 1
  • 16
  • 14
  • 4
    Absolute elegant answer. Thanks! Of-course without vue-router. – Yamen Ashraf Nov 02 '20 at 14:02
  • URLSearchParams is a pure javascript approach it's not a vuejs helper. – Muhammad Sep 22 '21 at 07:15
  • 1
    @mrded why is this approach better, given that Vue and apparently Vue Router is already used anyway? – Igor Dec 02 '21 at 19:00
  • 2
    @Igor because it's a JS native way and it works everywhere. Vue Router is just an unnecessary abstraction. – mrded Dec 03 '21 at 15:38
  • Worked on vue CDN => index.html?youParams=xxx – Bcktr Jan 09 '22 at 01:35
  • This is where I announce to you that some apps are also using SSR ([hi Nuxt](https://nuxtjs.org/docs/concepts/nuxt-lifecycle#nuxt-lifecycle)) and hence, where `window` is not available. This is indeed a bad approach, nothing elegant here so far. Please use the given APIs provided by Vue's ecosystem. Vue-router is reactive, and comes with several things in mind, if it was created there is a valid reason. It is not a thing done just for fun. I hope nobody is using `window.location.href` here, otherwise everybody is nuking their SPA. – kissu Dec 03 '22 at 16:46
59

More detailed answer to help the newbies of VueJS:

  • First define your router object, select the mode you seem fit. You can declare your routes inside the routes list.
  • Next you would want your main app to know router exists, so declare it inside the main app declaration.
  • Lastly the $route instance holds all the information about the current route. The code will console log just the parameter passed in the url. (*Mounted is similar to document.ready, i.e. it's called as soon as the app is ready)

And the code itself:

<script src="https://unpkg.com/vue-router"></script>
var router = new VueRouter({
    mode: 'history',
    routes: []
});
var vm =  new Vue({
    router,
    el: '#app',
    mounted: function() {
        q = this.$route.query.q
        console.log(q)
    },
});
kissu
  • 40,416
  • 14
  • 65
  • 133
Sabyasachi
  • 1,484
  • 12
  • 20
  • 3
    For even more clueless newbies: VueRouter isn't included in VueJS core, so you may want to include the VueRouter separately: `` – rustyx Sep 07 '17 at 09:15
  • 2
    @Sabyasachi Edit your answer and add that information within the post itself. – Simon Forsberg Oct 24 '17 at 20:29
  • 1
    `new Vue({ router, ... })` is not valid syntax. – Crescent Fresh Jan 24 '18 at 16:32
  • The script has partial ES6 usage which I think is making things worst for newcomers. Either go full ES6 with the proper variable decleration and arrow functions or use the traditional way. – Muhyee Mar 01 '18 at 16:28
  • @CrescentFresh new Vue({ router, ... }) is shorthand in ES6. In normal javascript is new Vue({ 'router': router, ... }) – Muhyee Mar 01 '18 at 16:29
51

Another way (assuming you are using vue-router), is to map the query param to a prop in your router. Then you can treat it like any other prop in your component code. For example, add this route;

{ 
  path: '/mypage', 
  name: 'mypage', 
  component: MyPage, 
  props: (route) => ({ foo: route.query.foo }),  
}

Then in your component you can add the prop as normal;

props: {
  foo: {
    type: String,
    default: null,
  }
},

Then it will be available as this.foo and you can do anything you want with it (like set a watcher, etc.)

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Mike P
  • 2,797
  • 2
  • 21
  • 25
  • 5
    This is great. The missing piece to the puzzle is the initiation. You can do that like this: ` this.$router.push({ name: 'mypage', query: { foo: 'bar' })` – slf Oct 26 '19 at 20:26
40

Vue 3 Composition API

(as far as now 2021, vue-router 4)

import {useRoute} from "vue-router";

//can use only in setup()
useRoute().query.test

or

//somewhere in your src files
import router from "~/router";

//can use everywhere 
router.currentRoute.value.query.test  

or

import {useRouter} from "vue-router";

//can use only in setup()
useRouter().currentRoute.value.query.test
Alexandr
  • 921
  • 7
  • 16
  • 1
    FYI to anyone reading this, the first import statement should be import { useRoute } from "vue-router" – nth-child Oct 06 '21 at 03:56
  • I am using the third example. I am trying console.log(useRouter().currentRoute.value.query.test) in the setup() and getting the error: "injection "Symbol([vue-router]: router)" not found. ". I installed vue-router@next and imported the useRouter...any ideas why I get this error? – St. Jan Nov 03 '21 at 18:01
  • 1
    @WillyBurb seems like you didn’t inject vue-router to vue. Go back to documentation, search for app.use(router) – Alexandr Nov 03 '21 at 21:38
  • three alternatives with custom imports, instead of simple "this.$route.query.test" – Victor Gavro Jan 26 '22 at 16:40
  • @VictorGavro "this.$route.query.test" works only with vue2 syntax, the answer is dedicated for people searching for Vue3 Composition API, as mentioned in the title and code comments of my solution – Alexandr Jan 27 '22 at 17:30
16

As of this date, the correct way according to the dynamic routing docs is:

this.$route.params.yourProperty

instead of

this.$route.query.yourProperty
doppelgreener
  • 4,809
  • 10
  • 46
  • 63
Marco
  • 2,757
  • 1
  • 19
  • 24
  • 10
    They are not the same thing! You should use `query` to get the queries from the URL. From the docs: In addition to $route.params, the $route object also exposes other useful information such as $route.query (if there is a query in the URL) – hatef Sep 13 '19 at 11:31
  • 3
    Your answer is wrong, this is not the "correct way". To explain a little, with `{ path: '/user/:id' }`, the url `/user/123?a=b&c=d` will have `$route.params == { id: "123" }` and `$route.query == { a: "b", c: "d" }`. – phil294 Jan 09 '21 at 13:23
  • a have linked the docs from vue, so if you say im wrong, doc is wrong. – Marco Jan 12 '21 at 03:42
  • 1
    I see you misunderstanding something here `params` means the parameters in your `URL` like `/user/:username`. You see that the `username` is `params` but `query params` are alike this `/search/?q='new Vue js'`, As you see, the `new Vue js` is a query param here. And there is nothing in the document that proves your answer. Please tell me which line of the document you see those? – Iman Shafiei Apr 27 '21 at 05:37
  • At the time the docs where for the 2.x version. You see many people upvoted, so it worked like that at some point. – Marco Apr 27 '21 at 14:54
  • People who upvoted mainly got confused as to params or queries to use. It doesn't mean that it is properly answering the question. The is quite a huge difference between the two as explained in the comments above. Vue's version has nothing to do here. – kissu Dec 03 '22 at 17:11
  • As of this date, the correct way to write a loop is to use an if statement – nosbor Dec 12 '22 at 21:00
  • @nosbor what are you saying here? – kissu Dec 13 '22 at 00:29
6

You can use vue-router.I have an example below:

url: www.example.com?name=john&lastName=doe

new Vue({
  el: "#app",
  data: {
    name: '',
    lastName: '',
  },
  beforeRouteEnter(to, from, next) {
    if(Object.keys(to.query).length !== 0) { //if the url has query (?query)
      next(vm => {
        vm.name = to.query.name;
        vm.lastName = to.query.lastName;
      });
    }
    next();
  }
})

Note: In beforeRouteEnter function we cannot access the component's properties like: this.propertyName.That's why i have pass the vm to next function.It is the recommented way to access the vue instance.Actually the vm it stands for vue instance

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Roland
  • 24,554
  • 4
  • 99
  • 97
  • In latest Laravel + Vue setup with the link `site.com/route?query=test` the `query` param returns `undefined` when accessed via the `to` param in the `beforeRouteEnter(to, from, next)` method. Any ideas why this could be so? – askepott Nov 15 '20 at 18:00
6

If your url looks something like this:

somesite.com/something/123

Where '123' is a parameter named 'id' (url like /something/:id), try with:

this.$route.params.id
NobodySomewhere
  • 2,997
  • 1
  • 16
  • 12
  • This is not a query param. Give a quick read to that one: https://stackoverflow.com/questions/35914069/how-can-i-get-query-parameters-from-a-url-in-vue-js/74668845#comment116059358_57479373 – kissu Dec 03 '22 at 17:11
5

Here is how to do it if you are using vue-router with vue3 composition api

import { useRoute } from 'vue-router'

export default {
  setup() {
    const route = useRoute()
    console.log(route.query)
  }
}
devnomic
  • 697
  • 8
  • 11
2

Example url: http://localhost:9528/#/course/outline/1439990638887137282

Below codes output: 1439990638887137282

this.courseId = this.$route.params.id
console.log('courseId', this.courseId)
duyuanchao
  • 3,863
  • 1
  • 25
  • 16
2

On top of the answers here, I recommend that you use the Vue devtools for further debugging.

Given this snippet of code

<template>
  <div>
    {{ showOrNotTheMessage }}
  </div>
</template>

<script>
export default {
  computed: {
    showOrNotTheMessage() {
      return this.$route.query?.lookingforthis
        ? 'Show this message'
        : 'Dont show this message'
    },
  },
}
</script>

This one will mainly display a conditional string as an example.


If you want to further debug what you're doing (with either Options or Composition API), you can select the root component in your Vue devtools and then access the whole Vue instance in your console with

$vm0.$route.query

PS: in Vue3, you need to use the following to access the Vue instance via the Devtools.

$vm0.proxy.$route.query

enter image description here

That can help you debug your code faster and potentially find cool stuff to play with.

kissu
  • 40,416
  • 14
  • 65
  • 133
1

one thing to keep in mind if you are using Hash mode then don't use this.$route.params.name only use url search param

Muhammad
  • 339
  • 3
  • 22