Vue.js routes send to 404 on refresh - vue.js

I have made routes, if click on link in website it works as it should. But when you on that page (for example /aboutUs) and refresh it or simply copy url, paste it and hit Enter it shows Page not found. How to fix it? Run out of ideas, can't find answer that works anywhere
main.js below:
Vue.config.productionTip = false;
Vue.use(VueRouter);
Vue.prototype.$careerEmpty = false;
const router = new VueRouter({
mode:'history',
scrollBehavior(to, from, savedPosition){
if (to.hash) {
return { selector: to.hash}
} else if (savedPosition) {
return savedPosition;
} else {
return {x:0, y:0}
}
},
routes
});
new Vue({
router,
render: h => h(App),
}).$mount('#app')
routes.js below:
import firstPage from "#/components/Pages/firstPage";
import aboutUsPage from "#/components/Pages/aboutUsPage";
import pageNotFound from "#/components/pageNotFound";
const routes = [
{path: '/', component: firstPage},
{path: '/aboutUs', component: aboutUsPage},
{path: '/404', component: pageNotFound},
{path: '*', redirect: '/404'},
];
export default routes;

You can use vue router history mode.
Check here
Vue.use(Router, {
mode: 'history'
});

Related

correct setting prerender-spa-plugin

I am trying to configure a prerender-spa-plugin for my application.
Need to configure for multiple pages.
I do, as in documentation (Vue.js 2 Router)
I added the necessary parameters to file webpack.prod.config.js
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const webpackConfig = merge(baseWebpackConfig, {
...
plugins: [
// == PRERENDER SPA PLUGIN == //
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, '../dist'),
routes: ['/', '/test'],
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
renderAfterDocumentEvent: 'render-event'
})
}),
...
Also in the file main.js
new Vue({
el: '#app',
router,
render: h => h(App),
mounted () {
// You'll need this for renderAfterDocumentEvent.
document.dispatchEvent(new Event('render-event'))
}
})
Now about the main problem.
At the root(/) of the project, pre-rendering is working.
If you go to the page /test, then in the source code (ctrl + u) will show the code from the site root(/).
I can't find content from /test in any way.
Tell me what I'm doing wrong, and how to fix the problem.
Thank!
UPD:routes.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
import test from '#/components/test'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/test',
name: 'test',
component: test
}
]
})

VueJS : Routing confusion

probably a stupid question especially as I am not sure if I am using VueJS or VueJS 2.0 but I am trying to get simple routing working where I can pick up the parameters / the path of the URL.
For example http://127.0.0.1/search/*****
Here is my main.js
import Vue from 'vue'
import App from './components/App'
import VueRouter from 'vue-router'
const routes = [
{ path: '/', name: 'Home', component: App },
{ path: 'search/:id', name: 'Search', component: App }
];
const router = new VueRouter({ mode: 'history', routes: routes });
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
render: h => h(App)
})
And on my App.component I am trying to get the :id
created: function() {
//this.filterTutorials();
this.searchTerm = this.$route.query.id;
if (this.searchTerm == null) {
this.searchTerm = this.$route.params.id;
}
console.log(this.searchTerm)
}
UPDATE
App and search were the same component but I have not split them out (same directory)
New main.js. It is not even calling the search page
import Vue from 'vue'
import App from './components/App'
import VueRouter from 'vue-router'
const routes = [
{ path: '/', name: 'Home', component: App },
{ path: '/search/:id', name: 'Search', component: () => import(/* webpackChunkName: "search" */ './components/Search.vue'), props: true }
];
const router = new VueRouter({ mode: 'history', routes: routes });
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
render: h => h(App)
})
I have also updated webpacks
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
vue: 'vue/dist/vue.js'
}
},
In your case, App is statically created before the route even resolves, so the created lifecycle hook would check for route parameter before it even existed (i.e., it would be undefined). I noticed both /search and / point to App, but you probably meant a component name like Search.
You can either dynamically import Search:
const routes = [
{
path: '/search/:id',
name: 'Search',
component: () => import(/* webpackChunkName: "search" */ './views/Search.vue')
}
]
Or you could use VueRouter's props: true to automatically set Search's id prop on navigation, obviating the check for the route parameters from created().
const routes = [
{
path: '/search/:id',
name: 'Search',
component: () => import(/* webpackChunkName: "search" */ './views/Search.vue'),
props: true,
}
]
demo

Vue i18n - adding locale to the URL using routerview

I am using a scafolded AspNetCore 2.1 site with VueJS using TypeScript.
I'm trying to integrate the kazupon i18n plugin with the router-view. Without the URL integration, it works just fine.
I am not able to get the proper redirects working like http://localhost/en/product and http://localhost/fr/product
This is the initial boot.ts, that uses VueI18n
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueI18n from 'vue-i18n'
Vue.use(VueRouter);
Vue.use(VueI18n);
import { messages, defaultLocale } from './lang/i18n';
const i18n = new VueI18n({
locale: defaultLocale,
fallbackLocale: 'en',
messages
})
const routes = [
{ path: '/', component: require('./components/home/home.vue.html') },
{ path: '/product', component: require('./components/product/product.vue.html') },
];
const router = new VueRouter({
mode: 'history',
routes: routes
});
new Vue({
el: '#app-root',
router: router,
i18n: i18n,
render: h => h(require('./components/app/app.vue.html'))
});
So far I have tried prefixing routes but it just breaks the functionality:
const routes = [{
path: '/',
redirect: `/${defaultLocale}`,
},
{
path: '/:locale',
children: [
{ path: '/', component: require('./components/home/home.vue.html') },
{ path: '/counter', component: require('./components/product/product.vue.html') },
]
}];
I've also tried relying on router.beforeEach to set the locale.
router.beforeEach((to, from, next) => {
let language = to.params.locale;
if (!language) {
language = 'en';
}
i18n.locale = language;
next();
});
This does not function either.
I've drawn inspiration from github.com/ashour/vuejs-i18n-demo and vue-i18n-sap-multilingual-best-practice, but it seems that during the i18n migration, some samples may have been obsolete or lost and those use-cases no longer function.
what you primarily needed is to specify the base option in the vue-router constructor.
But first, you need to extract the locale from the url:
let locale = window.location.pathname.replace(/^\/([^\/]+).*/i,'$1');
and then specify the base in your VueRouter constructor:
const router = new VueRouter({
...
base: (locale.trim().length && locale != "/") ? '/' + locale : undefined
...
});
and last but not the least, pass the locale into your VueI18n constructor:
const i18n = new VueI18n({
locale: (locale.trim().length && locale != "/") ? locale : defaultLocale,
fallbackLocale: 'en',
messages
})
See the updated example:
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueI18n from 'vue-i18n'
Vue.use(VueRouter);
Vue.use(VueI18n);
import { messages, defaultLocale } from './lang/i18n';
var locale = window.location.pathname.replace(/^\/([^\/]+).*/i,'$1');
const i18n = new VueI18n({
locale: (locale.trim().length && locale != "/") ? locale : defaultLocale ,
fallbackLocale: 'en',
messages
})
const routes = [
{ path: '/', component: require('./components/home/home.vue.html') },
{ path: '/product', component: require('./components/product/product.vue.html') },
];
const router = new VueRouter({
base: (locale.trim().length && locale != "/") ? '/' + locale : undefined,
mode: 'history',
routes: routes
});
new Vue({
el: '#app-root',
router: router,
i18n: i18n,
render: h => h(require('./components/app/app.vue.html'))
});
Thank you very much #Julian Paolo Dayag, there were three problems with the approach in my question:
it requires a redirect to "/" + defaultLocale + to.path
the children routes shouldn't start with /, they should be product instead of /product
The router.beforeEach... is no longer needed
I ended up with this code:
const routes = [
{
path: "/",
redirect: `/${defaultLocale}`
},
{
path: `/(fr|en)`,
component: require("./components/app/routertemplate.vue.html"),
children: [
{ path: "", component: require("./components/home/home.vue.html") },
{
path: "product",
component: require("./components/product/product.vue.html")
}
]
},
{
path: "/(.*)",
redirect: (to: any) => {
return "/" + defaultLocale + to.path;
}
}
];

VUEJS remove added routes or clear added routes

Good Day Everyone,
I'm trying to remove the addedRoutes on vuejs.. after doing hours of research on vue-router documentation I can't find a method that can clear the addedRoutes.
Here's my code:
new Vue({
el: '#app',
render: h => h(App),
router:router,
data(){
return{
isAuth:null
}
},
created(){
this.checkAuthentication();
if(this.isAuth){
this.getUserRole();
}
bus.$on('reload', (passData) => {
this.getUserRole();
if(this.isAuth){
this.getUserRole();
}
});
},
methods:{
getUserRole(){
this.$http.get('api/users/getRole').then(response => {
console.log(response);
if(response.body.is_admin){
router.addRoutes(Routes);
}else if(response.body.is_buh){
router.addRoutes(BUHRoutes);
}else if(response.body.is_so) {
}
});
},
checkAuthentication(){
this.isAuth = this.$auth.isAuthenticated();
}
}
});
my scenario is that when I login and if it is successful I get the userRole and based on that user role I add the routes router.addRoutes() based on the userRole. however, when I logout I get this warning on my console log [vue-router] Duplicate named routes definition: { name: "division-maintenance", path: "/division-maintenance" }. that's why I was doing a research on how to clear the addedRoutes.
any help will be appreciated.
I create a example file with vue-route
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
export default new Router({
base: process.env.BASE_URL, //config url base
routes: [
{
path: '/home',
name: 'home',
component: Home
},
],
mode: 'history'
})
The property mode: 'history' removes #

How do I link the route to the component using vue-router?

I'm trying to use vue-router to link url's to their corresponding components.
My issue is that only the root url ('/') can link to the correct component and any other url (e.g. '/first') does not link to their component. All of them link to the component which belongs to the '/' url.
When I use "a" tag in the vue file it will route to the right component - it's only when I input the url directly into the browser that it doesn't work
main.js:
import Vue from 'vue'
import router from './router/index.js'
Vue.use(ElementUI)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
// components: { App },
render: h => h(App)
})
index.js:
import Vue from 'vue'
import Router from 'vue-router'
import Hello from '../components/Hello.vue'
import First from '../components/firstPage.vue'
import Login from '../components/logIn.vue'
Vue.use(Router)
const routes =[
{
path: '/',
component: Login
},
{
path:'/first',
component:Hello
}
]
const router = new Router({
routes
})
export default router
I think you can also try as below. It's works, just try it! You can add mode: 'hash', to give default # in all urls.
import Vue from 'vue';
import Router from 'vue-router'
import Hello from '../components/Hello.vue'
import First from '../components/firstPage.vue'
import Login from '../components/logIn.vue'
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'hash',
base: '/your_base_name_if_you_want',
linkActiveClass: 'active-tab', //if you w
routes: [
{
path: '/',
redirect: '/if_you_want_to_redirect',
name: 'Login', //Whatever
component: {
render (c) { return c('router-view'); }
},
children: [
{
path: '/',
component: Login
name: 'Login',
meta: { title: 'Your title name' }
},
{
path:'/first',
component:Hello
name: 'Hello',
meta: { title: 'Your title name' }
}
]
}
]
})
export default router
You can also remove it from your urls using:
var router = new VueRouter({
history: true
});
Hope this helps you!
The default mode for vue-router is hash mode
This is why you can't get the 'Hello' component when your url is '/first'. Instead you can try input '/#/first'.
If you want to use history mode like '/first', set the mode attribute for your route object like this.
const router = new Router({
mode: 'history',
routes
})
Hope it helps you.