Can vue-router open a link in a new tab?
Asked Answered
A

15

199

I have a summary page and a detail subpage. All of the routes are implemented with vue-router (v 0.7.x) using programmatic navigation like this:

this.$router.go({ path: "/link/to/page" })

However, when I route from the summary page to the subpage, I need to open the subpage in a new tab just as one would by adding _target="blank" to an <a> tag.

Is there a way to do this?

Adolpho answered 13/10, 2016 at 7:39 Comment(4)
I dont think thats possible with vue router, you might extract and build your url and then use window.open(url, '_blank')Unto
Yes, they officially say it's impossible. Thank you.Adolpho
there is an answer below that works, you should accept that as the response on your question, don't you think?Ehman
i go over all the answers and only thing i did was adding target="_blank" to inside my router-link tag. but i am not sure if this is good practice or not. and I don't have any paramChaplin
P
363

I think that you can do something like this:

const routeData = this.$router.resolve({name: 'routeName', query: {data: "someData"}});
window.open(routeData.href, '_blank');

It worked for me.

Update


For composition Api:

import { useRouter } from 'vue-router'
const router = useRouter();
const routeData = router.resolve({name: 'routeName', query: {data: "someData"}});
window.open(routeData.href, '_blank');
Pages answered 18/12, 2017 at 19:4 Comment(7)
This seems like the best way to me. You still use $router to build the url without having to mash together some hacky string, then use window to open the new tab. +1Systematist
Unfortunately this method get block by some default browser popup blockerPinnatifid
Note that location parameter uses path instead of name if you use query.Louth
One problem with this is that window.open does not pass headers like tokens and others.Polka
@Rafel, May i ask you to have a look at a Vue.JS question related with the source code in github of the book 'Full-Stack Vue.js 2 and Laravel 5' by Anthone Gore here #59246077 ? Particularly take a look at the EDIT: section of the OP ?Mohsen
Create a link instead, like <a :href="getPath" target="_blank">...</a> ; avoid using Javascript to open links for accessibility, SEO & security reasons. What's more a link will still work even if there're errors in your JS code that break your app.Rockoon
In addition... if you don't want to open a new tab that is already open. It's possible to configure the target with an id of the refereced value with some other identification. Like window.open(routeData.href, 'details ' + id);Siebert
P
224

It seems like this is now possible in newer versions (Vue Router 3.0.1):

<router-link :to="{ name: 'fooRoute'}" target="_blank">
  Link Text
</router-link>
Prosector answered 4/4, 2018 at 15:2 Comment(5)
Doesnt seem to be that you can pass parameters though? just open the link itself. Correct?Reremouse
@Reremouse you can pass params and queryparams also. The code shall for doing that is given below <router-link :to="{ name: 'fooRoute',params:{param_var:'id_parameter'},query:{query_var:'query_params'}}" target="_blank"> Link Text </router-link>Bunde
Note that this is for the <router-link>, it doesn't work programmatically with this.$router.push().Amentia
adding target property in the router-link. This is awesome. The answer above by @Harish seem to work as well if we need the logic in the routes declarations.Tapir
<router-link :to="{ name: 'fooRoute', params: { id: 132 } }"> Link Text </router-link>Alitta
C
25

For those who are wondering the answer is no. See related issue on github.

Q: Can vue-router open link in new tab progammaticaly

A: No. use a normal link.

Conference answered 13/10, 2016 at 22:59 Comment(3)
Now possible to add target="_blank" to a <router-link> tag in v3 https://mcmap.net/q/127459/-can-vue-router-open-a-link-in-a-new-tabCashbox
Found this very helpful instead of constructing the full URL and using window.openFrierson
A: Yes for Vue 3+, now its possible: https://mcmap.net/q/127459/-can-vue-router-open-a-link-in-a-new-tabSiebert
D
21

In case that you define your route like the one asked in the question (path: '/link/to/page'):

import Vue from 'vue'
import Router from 'vue-router'
import MyComponent from '@/components/MyComponent.vue';

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/link/to/page',
      component: MyComponent
    }
  ]
})

You can resolve the URL in your summary page and open your sub page as below:

<script>
export default {
  methods: {
    popup() {
      let route = this.$router.resolve({path: '/link/to/page'});
      // let route = this.$router.resolve('/link/to/page'); // This also works.
      window.open(route.href, '_blank');
    }
  }
};
</script>

Of course if you've given your route a name, you can resolve the URL by name:

routes: [
  {
    path: '/link/to/page',
    component: MyComponent,
    name: 'subPage'
  }
]

...

let route = this.$router.resolve({name: 'subPage'});

References:

Droopy answered 22/3, 2018 at 15:39 Comment(0)
O
13

Somewhere in your project, typically main.js or router.js

import Router from 'vue-router'

Router.prototype.open = function (routeObject) {
  const {href} = this.resolve(routeObject)
  window.open(href, '_blank')
}

In your component:

<div @click="$router.open({name: 'User', params: {ID: 123}})">Open in new tab</div>
Overcome answered 19/3, 2019 at 9:22 Comment(2)
Not down-voting, but maybe it's nice for Vue3? Because console/logging this.$router.open returns undefined for meHidebound
This approach is discouraged as it mutates prototype. You can't log it, because it isn't part of the spec.Davisson
P
13

This worked for me-

let routeData = this.$router.resolve(
{
  path: '/resources/c-m-communities', 
  query: {'dataParameter': 'parameterValue'}
});
window.open(routeData.href, '_blank');

I modified @Rafael_Andrs_Cspedes_Basterio answer

Pictor answered 19/2, 2020 at 6:35 Comment(0)
U
11

Just write this code in your routing file :

{
  name: 'Google',
  path: '/google',
  beforeEnter() {                    
                window.open("http://www.google.com", 
                '_blank');
            }
}
Uriisa answered 7/8, 2019 at 8:56 Comment(0)
O
8

I think the best way is to simply use:

window.open("yourURL", '_blank');
Ommatophore answered 27/11, 2018 at 7:28 Comment(0)
O
6

If you are interested ONLY on relative paths like: /dashboard, /about etc, See other answers.

If you want to open an absolute path like: https://www.google.com to a new tab, you have to know that Vue Router is NOT meant to handle those.

However, they seems to consider that as a feature-request. #1280. But until they do that,



Here is a little trick you can do to handle external links with vue-router.

  • Go to the router configuration (probably router.js) and add this code:
/* Vue Router is not meant to handle absolute urls. */
/* So whenever we want to deal with those, we can use this.$router.absUrl(url) */
Router.prototype.absUrl = function(url, newTab = true) {
  const link = document.createElement('a')
  link.href = url
  link.target = newTab ? '_blank' : ''
  if (newTab) link.rel = 'noopener noreferrer' // IMPORTANT to add this
  link.click()
}

Now, whenever we deal with absolute URLs we have a solution. For example to open google to a new tab

this.$router.absUrl('https://www.google.com)

Remember that whenever we open another page to a new tab we MUST use noopener noreferrer.

Read more here

or Here

Outspread answered 24/3, 2020 at 10:29 Comment(1)
works well for me on almost all devices except mobile phones, where the new window does not open!Bambino
L
3

The simplest way of doing this using an anchor tag would be this:

<a :href="$router.resolve({name: 'posts.show', params: {post: post.id}}).href" target="_blank">
    Open Post in new tab
</a>
Lecce answered 30/9, 2020 at 14:57 Comment(0)
S
2

Below code is to open a new tab with parameter.

With router link=

<router-link
                  :to="{ name: 'task_section',query: {reportId: item.task,}}"
                  target="_blank"> Link Text
              </router-link>

Now access to the sented data

this.$route.query.reportId
Schuh answered 20/12, 2021 at 7:41 Comment(0)
T
1

It can be achieved by creating a separate method for window redirect like this.

const openLinkInNewTab = (url) => {
  window.open(url, '_blank');
}

then use it on template like this

<a href="javascript:void(0)" @click="openLinkInNewTab('https://devsbuddy.com')">
    Open in new tab
</a>
Thenceforward answered 27/3, 2022 at 17:45 Comment(0)
T
0

This works for me:

In HTML template: <a target="_blank" :href="url" @click.stop>your_name</a>

In mounted(): this.url = `${window.location.origin}/your_page_name`;

Teledu answered 20/7, 2020 at 13:27 Comment(0)
W
0

you can use it in vue3 & typescript

import { useRouter } from "vue-router";
const router = useRouter();
let route = router.resolve({ name:'/link/to/page' , query: { param: 'param1' } });
window.open(route.fullPath, "_blank");
Wendall answered 15/11, 2023 at 5:55 Comment(0)
F
0

use following code for apache server

<IfModule mod_negotiation.c>
  Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
Front answered 17/1 at 15:4 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Profant

© 2022 - 2024 — McMap. All rights reserved.