how to add # in route in nuxtjs. e.g: example.com/#username - vue.js

I have been searching to how to add a # in dynamic route in nuxtjs.
I want to achieve example.com/#username
I have tried to create a directory named '#' and inside it i created a file _user.vue but that leads to #/username
I have also tried to extend router in config and create a custom route like
router: {
extendRoutes(routes, resolve) {
routes.push({
name: 'user',
path: '/(#):username',
component: resolve(__dirname, 'pages/userProfile.vue')
})
}
},
but nuxt is preventing it & throwing error:
Expected "0" to match "#", but received "%40"
What i understand with this, is, it is url-encoding the # sign and username.
how do i achieve my desired output, (it is possible in vue router) as discussed in this below issue
https://github.com/vuejs/vue-router/issues/499
Any help will be appreciated.
Thanks!

Nvm.
I have just fixed it myself. posting answer to help others;
Nuxt doesnt support #_username.vue route name in nuxt filesystem routing.
to achieve route as example.com/#username we need to extend it in nuxt.config.js file in router object and define our custom route as
router: {
extendRoutes(routes, resolve) {
routes.push({
name: 'user',
path: '/#:username',
component: resolve(__dirname, 'pages/userProfile.vue')
})
}
},
defination of route is exactly same as vue router, as nuxt implements vue router.
so here,
name property is route name
path property is route path (prv. i was trying it (#):username which was leading to error, & it just got fixed when i removed brackets)
component property is page/component file name and it can exist anywhere, just set the file path where it exists.
Thanks me later!
cheers

Related

How to change base url in VUE router?

Current URL is 'https://localhost:3000/lang/countries/states/cities/'
I want to change it to:
https://localhost:3000/lang/compare/?c=1&back=1&query=94&query=911
Basically I want to edit the current URL. I tried using:
this.$router.push({
path:'/lang/compare/?c=1&back=1&query=94&query=911',
});
this.$router.replace({
path:'/lang/compare/?c=1&back=1&query=94&query=911',
});
But this changes the URL to :
https://localhost:3000/lang/countries/states/cities/lang/compare/?c=1&back=1&query=94&query=911',
I have tried using window location href but coz of that state of my variable is lost, hence I need to use VUE router for this. Is their any way to change base URL in VUE routes.
Your method is also right it should work if there is no other issue,
try with
this.$router.push({ path: '/lang/compare', query: { c: 1,back:1,firstquery:94,queryB:991}})
or you can also try with $router name defining a name on router index file
{
path: "/lang/compare",
name: "compare",
component: comparePage,
},
this.$router.push({ name: 'compare', query: { c: 1,back:1,firstquery:94,queryB:991}})

How to set and change default(root) router with vue-router(Vue 3 Composition API)

I asked this at two other places but couldn't get a good answer. I would be grateful if anyone here could help me with this. I also think this may help other in the future.
My problem is a bit specific.
I am trying to set the "/" router to for example "/team-12" .
"team-12" is selected by user and stored in localStorage or store(Pinia).
So for example if the user selected a team, the default router will be /team-12/ (".com/team-12/settings" etc.). All the website routing will be added after "team-12/" If not selected it will be team-1 or something like that. And the user can change the team, thus the default route will change and page will refresh.
I managed to set the route to localStorage value but I get an error:
[Vue Router warn]: No match found for location with path "/team-12"
Also I can't add other routes to "/team-12". How can I achieve this? If there is a better aproach, ignore the code.
I tried this: router.ts
router.ts:
const contractId = localStorage.getItem("contractId");
{
path: "/",
name: "home",
redirect: `/${contractId}`,
component: Home,
},
Component:
const selectTeamId = (teamId: string) => {
localStorage.setItem("teamId", organization);
console.log(localStorage.getItem("teamId"));
router.push({ name: "home" });
};

Vuejs Router Async Component

I am running a vue app with npm run serve.
I am injecting the components to the routes asynchronously and in my opinion is happening something strange as when I am not even at that path it shows me an error about a component of another path, saying that the file is missing... and it is true it is missing... but isn't that suppose to be injected when I am at that path? Looks like the component is already imported...
const router = new VueRouter({
routes: [
{ path: '/login', component: () => import('./pages/login.vue') },
{ path: '/register', component: () => import('./pages/register.vue') },
]
I see this error in the compiler
./src/main.js
Module not found: Error: Can't resolve './pages/register.vue' in '/home/daniel/work/someapp/frontend/src'
and the path is /login, of course all works properly when I create the register page... just don't understand why it gets imported when the route is not loaded yet.
You are right.
You won't get the error until you navigate to that route that has the erroneous import path.
However, you have specified /login for both login and register.
So if the register component import path is not correct you will get the error.
Here is a trivial implementation which demonstrates the same.
When you navigate to categories, you will see an error. But home, news and lists will work correctly.

Data passing using props in router is not working

I am trying to send data from one vue component to another by using props in router. but it is not working. whenever i try to log the props it outputs undefined. code is given below
From where data is sending
Where receiving
in index.js. router setting
None of the code you've posted matches up.
Firstly, the console logging should be just console.log(this.myprops). The point of using props is that you don't need to reference the router itself, e.g. via $router.
Next problem, you're mixing path and params. That isn't allows. See https://router.vuejs.org/guide/essentials/navigation.html. params are for named routes.
I imagine what you're aiming for is something like this:
self.$router.replace({ name: 'DashboardPatient', params: { myprops: authUser.email } })
with router config:
{
path: '/patient',
component: Dash,
children: [
{
path: ':myprops', // <--- Adding myprops to the URL
name: 'DashboardPatient',
component: DashboardPatient,
props: true,
meta: { requiresAuth: true }
}
]
}
Keep in mind that routing is all about building and parsing the URL. So the value of myprops needs to be in the URL somewhere. In my example it comes at the end, so you'll get /patient/user#example.com as the URL. If it weren't in the URL then there'd be no way for the router to populate the prop if the user hit that page directly (or refreshed the page).
To hit the same route using a path instead of a name it'd be something like this:
self.$router.replace({ path: `patient/${encodeURIComponent(authUser.email)}` })
or even just:
self.$router.replace(`patient/${encodeURIComponent(authUser.email)}`)
Personally I'd go with the named route so that the encoding is handled automatically.
If you don't want to put the data in the URL then routing is not the appropriate way to pass it along. You'd need to use an alternative, such as putting it in the Vuex store.

Custom handling forward slashes in vue router ids

I have a use case for needing the id part of a vue route to contain unescaped forward slashes.
My current route looks like this:
{
path: '/browse/:path*',
component: browse,
name: 'browse',
displayName: 'Browse',
meta: { title: 'Browse' },
},
So when a user browses to the above url, the browse component is shown.
However, i want to use the id part of the path (:path*) to contain a nestable fielsystem like path to be consumed by my browse page.
For example the url /browse/project/project1 would take me two levels down in my tree to the project1 item.
Now, the problem i'm running into is that vue router is escaping my ids (path) when navigating programatically, and my url ends up like this: /browse/project%2Fproject1. This is non-ideal and does not look nice to the end user. Also, if the user does browse to /browse/project/project1 manually the app will work correctly and even keep the original encoding in the url bar.
So i could resolve this my making an arbitrary number of child paths and hope that the system never goes over these, but thats not a good way to solve my problem.
I should also clarify that the application will not know anything about the path after /browse as this is generated dynamically by the api that powers the app.
Is there a native way in vue-router to handale this? or should i change up how im doing things.
There is a more elegant solution without workarounds.
Vue router uses path-to-regexp module under the hood and constructions like
const regexp = pathToRegexp('/browse/:path*')
// keys = [{ name: 'browse', delimiter: '/', optional: true, repeat: true }]
https://github.com/pillarjs/path-to-regexp#zero-or-more
const regexp = pathToRegexp('/browse/:path+')
// keys = [{ name: 'browse', delimiter: '/', optional: false, repeat: true }]
https://github.com/pillarjs/path-to-regexp#one-or-more
set repeat flag to true. Any array parameter with repeat flag will be joined with the delimiter (default '/').
So you can pass a splitted array ['project','project1'] instead of 'project/project1' into router.push():
router.push( {name: 'browse', params: {path: ['project','project1']}} );
or
router.push( {name: 'browse', params: {path: 'project/project1'.split('/')}} );
So I managed to 'fix' this with a bit of a hack.
When creating my Vue router instance I am attaching a beforeEach function to replace any outgoing encodings of '/'. This will send the 'correct' URL I am looking for to the client.
const router = new Router({
mode: 'history',
routes,
});
router.beforeEach((to, from, next) => {
// hack to allow for forward slashes in path ids
if (to.fullPath.includes('%2F')) {
next(to.fullPath.replace('%2F', '/'));
}
next();
});
I just stumbled over your question while facing a similiar problem.
Think this is because an id shall identify one single resource and not a nested structure/path to a resource.
Though I haven't solve my problem yet, what you probably want to use is a customQueryString:
https://router.vuejs.org/api/#parsequery-stringifyquery
https://discourse.algolia.com/t/active-url-with-vue-router-for-facet-and-queries/3399
I fixed it by creating helpers for generating hrefs for :to attributes of vue router link.
First i made router accessible for my new helper service like here Access router instance from my service
Then i created router-helpers.js and here i made my helpers, here is an example
import Vue from 'vue'
import router from '../router.js'
// replace %2F in link by /
const hrefFixes = function(to) {
return to.replace(/%2F/g, '/')
}
// my link helper
Vue.prototype.$linkExample = attr => {
// create "to" object for router resolve
const to = { name: `route-name`, params: { param1: attr } }
// this will resolve "to" object, return href param as string
// and then i can replace %2F in that string
return hrefFixes(router.resolve(to).href)
}
Just include this service once in your Vue application an then just use this helper like this
<router-link :to="$linkExample(attr)">text</router-link>