VueJs vue-router linking an external website
Asked Answered
T

11

59

This may be simple, but I've looked over documentation and can't find anything about it. I want to have my 'github' link redirect to say, github.com. However, its just appending 'https://github.com' to my url instead of following the link. Here is a snippet:

 <BreadcrumbItem to='https://github.com'>
    <Icon type="social-github"></Icon>
 </BreadcrumbItem>

(This is using iView for custom CSS, but 'to' works in the same way as router-link).

What ends up happening is this: enter image description here

Trinitrophenol answered 31/5, 2018 at 21:24 Comment(6)
For external links, just use <a href="..."> to point directly to whatever you're linking to. vue-router is only needed for internal links.Squash
That doesn't really work, considering I can't use the <a> tag here, and its being abandoned for 'to'Trinitrophenol
For now, at least, that's how it works. The <a> tag is not being "abandoned"; to is a vue construct that gives the router a chance to rewrite the url to point back to the SPA. One way would be to build that logic into your BreadcrumbItem component, to use <a href="..."> if the attribute has a http(s) protocol or <router-link> otherwise.Squash
Thank you, someone in that thread had a good workaround as well.Trinitrophenol
Now that I look: Possible duplicate of Vue2 navigate to external url with location.href (One answer there includes another technique I hadn't known about -- "navigation guards" -- that may suit here if you only have a small number of external links to deal with)Squash
This is not a very good solution. What if I want to use :to="url" ?Ceramal
T
56

I read Daniel's Link and found a workaround:

{
     path: '/github',
     beforeEnter() {location.href = 'http://github.com'}
}
Trinitrophenol answered 31/5, 2018 at 21:43 Comment(3)
or w3schools.com/jsref/met_win_open.aspDeplorable
Heads up, doesn't work in Vue3. Need it for a <button> link.Edward
In Vue 3 add component propertyPenuche
B
39
<a :href="'//' + websiteUrl" target="_blank">
  {{ url }}
</a>
Byzantine answered 18/9, 2018 at 14:14 Comment(0)
I
19

If you use vuetify, you can use v-list-item, v-card or v-btn.

They all have a property target which you can set to _blank e.g.:

<v-list-item href="https://google.com" target="_blank">Google</v-list-item>
Impetrate answered 9/10, 2019 at 8:5 Comment(0)
O
16

I'm late to the party, but I think my solution is more simple and elegant:

<component
  :is="item.link.startsWith('http') ? 'a' : 'router-link'"
  v-for="item in navigationLinks"
  :key="item.link"
  :to="item.link"
  :href="item.link"
>
  {{ item.name }}
</component>
Omsk answered 16/9, 2022 at 6:20 Comment(1)
Although late to the party, this is indeed the solution that keeps things simple and makes relevant use of the Vue.js tools. The dynamic component approach is perfectly fitted here. Thanks !Amherst
T
12

You can either:

  • use a normal link <a href=...
  • use a @click handler and change window.location = http:// there.
Thumbsdown answered 31/5, 2018 at 21:30 Comment(3)
I think you cannot use window.location inside a click event handler. I should be window.location.href = "http://...."Welty
No. I want to be able to right-click the link.Ceramal
No. I want to be able to use :to="var" without having 2 solutions in one component.Ceramal
M
5

const github = { template: '<div>github</div>'}

	const routes = [
		{ 
			path: '/github',
			beforeEnter() {location.href = 'http://github.com'},
			component: github
		}
		]

	const router = new VueRouter({
		routes
		})

	const app = new Vue({
		router
		}).$mount('#app')
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	  <script src="https://unpkg.com/vue/dist/vue.js"></script>
	  <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    </head>
<body>    
<div id="app">
  <li><router-link to="/github">github.com</router-link></li>
  <router-view></router-view>
</div>
</body>
Mezzorilievo answered 25/5, 2019 at 9:20 Comment(1)
This is overkill for a simple function.Orotund
T
5

A more dynamic way if you need it is to just override certain methods to detect when a route should be handled in an external manner using route.meta.external:

  // Override matcher to fix external links.
  const match = router.matcher.match
  router.matcher.match = (...args) => {
    let route = match.apply(router, args)
    if (!route.meta.external) {
      return route
    }
    return Object.freeze({...route, fullPath: route.path})
  }

  // Override resolver to fix external links.
  const resolve = router.resolve
  router.resolve = (...args) => {
    const resolved = resolve.apply(router, args)
    if (resolved.route.meta.external) {
      resolved.href = resolved.route.fullPath
    }
    return resolved
  }

  // Handle external routes.
  router.beforeEach((to, from, next) => {
    if (to.meta.external) {
      if (to.meta.newWindow) {
        window.open(to.fullPath)
      }
      else {
        window.location.replace(to.fullPath)
      }
      return next(false)
    }
    next()
  })
Titfer answered 25/8, 2019 at 22:28 Comment(0)
K
2

Just put the link block inside the breadcrumb item like this:

 <BreadcrumbItem>
  <a href="https://github.com">
    <Icon type="social-github"/>
  </a>
 </BreadcrumbItem>
Kolosick answered 11/4, 2019 at 10:11 Comment(0)
Z
2

Just do "//" instead of http or https. This works for me in router file.

Zimmerman answered 18/9, 2021 at 18:38 Comment(1)
good solution for those who are using :hrefHardball
A
1

I would create a new route in my router config file with the route to my external link opening in a a new tab.

{
  name: "Github",
  beforeEnter() {
    window.open('https://www.github.com/', '_blank')
  },
  component: MyComponent,
},

Then in my template I would create a simple button that calls a function to the new route with the external link.

<button @click="onUserClick('Github')">Github</button>
setup () {
  const router = useRouter()
  const onUserClick = (linkTo) => {
    router.push({ name: linkTo })
  }
  return {onUserClick}
}

This will allow you have to multiple links to external routes very easily. IE social media pages without cluttering up your component.

Achromatous answered 10/1, 2022 at 22:37 Comment(0)
G
0

I was stuck with the same issue in Vue JS. Here are my codes. Not only does it lead to a new location but also opens a new tab.

<div id="top-socials">
 <ul>
    <li v-for="icon in socialIcons" :key="icon">
        <img @click="socialClicked(icon)" :src="icon" 
     style="width:25px;height:25px;"/>
    </li>

</ul>
</div>
  export default {
data(){
    return{
        socialIcons:[facebook,instagram,tiktok,youtube]
    }
},
  methods:{
  socialClicked(v){
   if(v.includes(tiktok)){
    console.log(v)
   }
   else if(v.includes(youtube)){
    var anchor = document.createElement('a');
    anchor.href = 'https://www.youtube.com/@novathewonderdog9404';
    anchor.target="_blank";
    anchor.click();

    console.log("You Tube was clicked")
   }
   else if(v.includes(instagram)){
    console.log("Instagram was clicked")
   }
   else if(v.includes(facebook)){
    console.log("Facebook was clicked")
   }
  }
}

I guess you could do the same with BreadCrumbs

Gazpacho answered 15/12, 2022 at 5:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.