Nuxt SSR routing problem - [vue-router] Duplicate named routes definition - vue.js

I am unable to fix the warnings displayed on the console:
this is my routes/index.js
module.exports = [
{
name:'shop-page',
path: '/sklepy/:id',
component: 'pages/shop-page.vue'
},
{
name: 'shops',
path: '/sklepy',
component: 'pages/shops-list-page.vue'
},
{
name: 'categories',
path: '/kategorie',
component: 'pages/category-list-page.vue'
},
{
name: "category-page",
path: '/kategorie/:id',
component: 'pages/category-page.vue'
},
{
name: 'rules',
path: '/regulamin',
component: 'pages/rules-page.vue'
},
{
name: 'privacy policy',
path: '/polityka-prywatnosci',
component: 'pages/privacy-policy-page.vue'
},
{
name: 'new password',
path: '/new-password',
component: 'pages/new-password-page.vue'
},
{
name: 'cookies policy',
path: '/polityka-cookies',
component: 'pages/cookies-page.vue'
},
{
name: 'email-confirmed',
path: '/email-confirmed',
component: 'pages/email-confirmed-page.vue'
},
]
And this is my nuxt.config.js
const routes = require('./routes/index.js')
export default {
css: [
'#/static/css/styles.css',
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{ src: "#/plugins/filters.js" },
{ src: "#/plugins/axios.js" }
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/tailwindcss
'#nuxtjs/tailwindcss',
'#nuxtjs/composition-api/module'
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
// https://go.nuxtjs.dev/pwa
'#nuxtjs/pwa',
'#nuxtjs/proxy',
'#nuxtjs/dotenv'
],
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
proxy: true
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
},
proxy: {
'/api/': {
target: process.env.VUE_APP_ROOT_API,
pathRewrite: { '^/api': '' }
}
},
router: {
extendRoutes(nuxtRoutes, resolve) {
routes.forEach((route) => {
nuxtRoutes.push({
name: route.name,
path: route.path,
component: resolve(__dirname, route.component)
})
})
}
}
}
these problems probably cause that when I reload the page from url:
http://localhost:3000/shops/4kom
(then click F5, refresh the page), the following appears:
http://localhost:3000/shop-page
Please, help.

Ok, the solution is:
the name cannot be the same as component.

you don't need to loop routes inside nuxt.config.js. try this.
routes/index.js
const extendRoutes = (routes, resolve) => {
routes.push(
{
name:'shop-page',
path: '/sklepy/:id',
component: 'pages/shop-page.vue'
},
{
name: 'shops',
path: '/sklepy',
component: 'pages/shops-list-page.vue'
},
{
name: 'categories',
path: '/kategorie',
component: 'pages/category-list-page.vue'
},
{
name: "category-page",
path: '/kategorie/:id',
component: 'pages/category-page.vue'
},
{
name: 'rules',
path: '/regulamin',
component: 'pages/rules-page.vue'
},
{
name: 'privacy policy',
path: '/polityka-prywatnosci',
component: 'pages/privacy-policy-page.vue'
},
{
name: 'new password',
path: '/new-password',
component: 'pages/new-password-page.vue'
},
{
name: 'cookies policy',
path: '/polityka-cookies',
component: 'pages/cookies-page.vue'
},
{
name: 'email-confirmed',
path: '/email-confirmed',
component: 'pages/email-confirmed-page.vue'
},
);
};
export default extendRoutes;
nuxt.config.js
import extendRoutes from "./routes/index.js";
export default {
router: {
extendRoutes
},
}

Related

Vue Router 4 - nested 404 (not found) routes redirect not working

these are my routes:
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: {},
children: [
{ path: "extensions", component: {} },
{ path: "themes", component: {} },
{ path: ":pathMatch(.*)*", redirect: "extensions" },
],
},
{
path: "/about",
component: {},
children: [
{ path: "experience", component: {} },
{ path: "documents", component: {} },
{ path: ":pathMatch(.*)*", redirect: "experience" },
],
},
{ path: "/:pathMatch(.*)*", redirect: "/projects/extensions" },
];
Expected result:
Navigating to /projects or /projects/asdasd -> redirects to /projects/extensions
Navigating to /about or /about/asdasd -> redirects to /about/experience
Navigating to /asdasdasd -> redirects to /projects/extensions
Current result:
Every incorrect path redirects me to /projects/extensions
I tried many combinations but nothing works as expected, please help.
Redirecting to child route
To redirect /projects to /projects/extensions, add a child route with a blank path that redirects to the target route:
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: () => import("../views/ProjectsView.vue"),
children: [
{
path: "",
redirect: "/projects/extensions", // or use a named route (see below)
},
⋮
],
},
}
Getting the redirect target right
When the redirect string is not an absolute path to a route (i.e., /about/experience), the path would be relative to the current route.
For instance, imagine being at /projects/themes and clicking /about/foo. This is how the final route would resolve:
/about/foo matches the wildcard route under /about, which redirects to /projects/themes/experience.
/projects/themes/experience matches the outer wildcard route, which redirects to /projects/extensions.
There are a couple ways to solve this...
Option 1: Use absolute path in redirect string
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: () => import("../views/ProjectsView.vue"),
children: [
{
path: "extensions",
component: () => import("../views/ProjectsExtensions.vue"),
},
{
path: "themes",
component: () => import("../views/ProjectsThemes.vue"),
}, 👇
{ path: ":pathMatch(.*)*", redirect: "/projects/extensions" },
],
},
{
path: "/about",
component: () => import("../views/AboutView.vue"),
children: [
{
path: "experience",
component: () => import("../views/AboutExperience.vue"),
},
{
path: "documents",
component: () => import("../views/AboutDocuments.vue"),
}, 👇
{ path: ":pathMatch(.*)*", redirect: "/about/experience" },
],
}, 👇
{ path: "/:pathMatch(.*)*", redirect: "/projects/extensions" },
]
demo 1
Option 2: Use named route in redirect object
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: () => import("../views/ProjectsView.vue"),
children: [
{
path: "extensions",
👇
name: "proj-ext",
component: () => import("../views/ProjectsExtensions.vue"),
},
{
path: "themes",
component: () => import("../views/ProjectsThemes.vue"),
}, 👇
{ path: ":pathMatch(.*)*", redirect: { name: "proj-ext" } },
],
},
{
path: "/about",
component: () => import("../views/AboutView.vue"),
children: [
{
path: "experience",
👇
name: "about-exp",
component: () => import("../views/AboutExperience.vue"),
},
{
path: "documents",
component: () => import("../views/AboutDocuments.vue"),
}, 👇
{ path: ":pathMatch(.*)*", redirect: { name: "about-exp" } },
],
}, 👇
{ path: "/:pathMatch(.*)*", redirect: { name: "proj-ext" } },
]
demo 2
Named routes are easier to maintain than paths, as (1) they avoid having to enter long paths, and (2) they could be moved without having to refactor paths.

Redirect from beforeEnter causes infitite cycle and does not redirect

I have a problem with the nonworking redirect. I check is the user is logged in and the info is right, but when it comes to redirecting it does not redirect and just goes in this beforeEnter over and over again. Can somebody say what am I doing wrong?
I am presenting here my RouteConfig and the problem with the first beforeEnter.
export const routes: RouteConfig[] = [
{ path: '*', redirect: '/' },
{
path: '/',
component: router_view,
async beforeEnter(to, from, next) {
var hasPermission = await storage.get('state').user.tokens.access;
console.log(!!hasPermission)
if (!!hasPermission && from.fullPath.startsWith('/')) {
return next('profile');
} else {
return next()
}
},
children: [
{
name: 'landing',
meta: { requiresAuth: false },
path: '',
component: require('pages/index').default
},
{
meta: { requiresAuth: true },
path: 'seller',
component: require('pages/seller').default,
children: [
{
path: '',
name: 'profile',
redirect: 'profile'
},
{
path: 'account',
component: require('pages/seller/account').default
},
{
path: 'help/:url?',
component: require('pages/seller/help').default
},
{
path: 'profile',
component: require('pages/seller/profile').default
},
{
path: 'finances/:shop?',
name: 'finances',
props: route => ({
...route.query,
...route.params
}),
component: require('pages/seller/finances').default
},
{
path: 'shop',
component: require('pages/seller/shop').default,
children: [
{
path: '',
redirect: 'main'
},
{
path: 'main',
component: require('pages/seller/shop/main').default
},
// {
// path: 'rating',
// component: require('pages/seller/shop/rating').default
// },
{
path: 'design',
component: require('pages/seller/shop/design').default
},
]
},
{
path: 'invoices',
redirect: { name: 'invoices-send' },
component: require('pages/seller/invoices/index').default,
children: [
{
path: 'send',
name: 'invoices-send',
component: require('pages/seller/invoices/send').default,
},
{
path: 'return',
name: 'invoices-return',
component: require('pages/seller/invoices/return').default
},
{
path: 'create-send',
component: require('pages/seller/invoices/createInvoice').default,
},
{
path: 'create-return',
component: require('pages/seller/invoices/createInvoice').default,
},
]
},
{
path: 'products',
component: router_view,
children: [
{
path: '',
redirect: 'all'
},
{
path: 'new',
component: require('pages/seller/products/new').default,
children: [
{
path: '',
component: require('pages/seller/products/new/createproduct').default
},
]
},
{
path: 'id/:productid/edit',
component: require('pages/seller/products/new').default,
children: [
{
path: '',
name: 'edit-product',
props: route => ({ ...route.params, ...route.query }),
component: require('pages/seller/products/new/createproduct').default
},
{
path: 'sku',
name: 'edit-product-sku',
component: require('pages/seller/products/new/createsku').default,
},
]
},
{
path: 'invoices',
redirect: { name: 'invoices-send' }
},
{
path: 'id/:productid',
component: require('pages/seller/products/_productid').default,
children: [
{
path: 'main',
name: 'product-page-solo',
component: require('pages/seller/products/_productid/main').default
},
// {
// path: 'reviews',
// component: require('pages/seller/products/_productid/reviews').default
// },
// {
// path: 'statistics',
// component: require('pages/seller/products/_productid/statistics').default
// },
{
path: 'printlabels',
name: 'product-labels-solo',
component: require('pages/seller/products/_productid/printlabels').default
},
]
},
{
path: 'stickers',
name: 'products-stickers',
component: require('pages/seller/products/stickers').default,
},
{
path: ':table',
name: 'product-list',
component: require('pages/seller/products/index').default,
props: _ => ({
tabletype: _.params.table
}),
beforeEnter(to, from, next) {
if (to.params.table === 'invoices') {
return next({ name: 'invoices' });
} else {
next();
}
},
children: [
{
path: 'id/:productid',
component: require('pages/seller/products/_productid').default,
children: [
{
path: 'main',
name: 'product-page',
component: require('pages/seller/products/_productid/main').default
},
// {
// path: 'reviews',
// component: require('pages/seller/products/_productid/reviews').default
// },
// {
// path: 'statistics',
// component: require('pages/seller/products/_productid/statistics').default
// },
{
path: 'printlabels',
name: 'product-labels',
component: require('pages/seller/products/_productid/printlabels').default
},
]
},
]
}
]
}
]
},
{
meta: { requiresAuth: false },
name: 'signin',
path: '/signin',
component: router_view,
children: [
{
path: '',
name: 'signin',
component: require('pages/signin/index').default
},
{
path: 'restore',
component: router_view,
children: [
{
path: '',
component: require('pages/signin/restore/index').default
},
{
path: 'password',
component: require('pages/signin/restore/newpassword').default,
beforeEnter(to, from, next) {
if (from.fullPath.startsWith('/confirm'))
return next();
else
return next('/');
}
}
]
}
]
},
{
path: 'confirm',
meta: { requiresAuth: false },
component: require('pages/confirm/index').default,
beforeEnter(to, from, next) {
const path = from.fullPath ? from.fullPath : from.path;
if (path === '/signin' || path === '/signup' || path === '/signin/' || path === '/signup/' || path === '/' || path === '/signin/restore' || path === '/signin/restore/'
|| (from.path.startsWith('/confirm') && from.query === to.query)
|| to.query.from === 'account'|| to.query.from === 'restore')
return next();
else
return next('/');
}
},
{
name: 'signup',
path: 'signup',
meta: { requiresAuth: false },
component: router_view,
children: [
{
path: '',
name: 'signup',
component: require('pages/signup/index').default
},
{
path: 'social',
component: require('pages/signup/social').default
},
]
},
{
meta: { requiresAuth: false },
path: 'terms-of-use',
component: require('pages/terms-of-use').default
}
]
}
];

"npm run dev" creates 0.js, 1.js, ... 14.js files in my public folder

I'm a beginner using Webpack, NPM and VueJS.
I dont know what I did and I can't find any solution on internet.
When I run the command npm run dev in VueJS, webpack creates 15 files numbered from 0.js to 14.js
The files first lines are :
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{
Where 0 in the file name
Anyone knows what I broke in my app ?
EDIT:
I figured out that every file is related to One component.
And I guess that this is in relation with my router file :
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
function loadView(view) {
return () => import(`../components/${view}.vue`);
}
function loadLayout(view) {
return () => import(`../components/_layouts/${view}.vue`);
}
const routes = [
// USER ROUTES
{
path: '/dashboard',
component: loadView('user/Dashboard'),
meta: {
layout: loadLayout('user/Layout'),
auth: "user"
},
name: 'user'
},
// SUPPLIER ROUTES
{
path: '/supplier',
component: loadView('supplier/Dashboard'),
meta: {
layout: loadLayout('supplier/Layout'),
auth: "supplier"
},
name: 'supplier'
},
// ADMIN ROUTES
{
path: '/admin',
component: loadView('admin/Dashboard'),
meta: {
layout: loadLayout('admin/Layout'),
auth: "admin"
},
name: 'admin'
},
// DEFAULT ROUTES
{
path: '/register',
component: loadView('auth/Register'),
meta: {
layout: loadLayout('home/Layout'),
auth: false
},
name: 'register'
},
{
path: '/login',
name: 'login',
component: loadView('auth/Login'),
meta: {
layout: loadLayout('home/Layout'),
auth: false
}
},
{
path: '/',
component: loadView('home/Home'),
meta: {
layout: loadLayout('home/Layout'),
auth: undefined
},
name: 'home'
},
// otherwise redirect to home
{
path: '*',
redirect: '/'
}
];
Vue.router = new Router({
hashbang: false,
mode: 'history',
routes
});
export default Vue.router;
To move those dynamic imports, you have to put this code in webpack.mix.js :
mix.webpackConfig({
output: {
chunkFilename: 'js/[name].js',
},
});

Angular, dynamic param on lazy loaded route not working

I have an Angular 8 App that has lazyloading working on all the pages, except for 2 that have dynamic parameters where something is not working correctly
From the app routing module
{
path: 'product',
loadChildren: './marketing/page/product/product-page.module#ProductPageModule'
},
From the ProductPageRoutingModule
const routes: Routes = [
{
path: '',
component: AppMarketingPageProductComponent,
children: [
{ path: ':slug', component: AppMarketingPageProductComponent },
{ path: ':slug', component: AppMarketingPageProductComponent },
{ path: ':slug/:secondary', component: AppMarketingPageProductComponent },
]
}
];
Routes are being put into the imports correctly, and the ProductRoutingModule is imported into ProductPageModule.
#NgModule({
imports: [
RouterModule.forChild(routes)
],
exports: [
RouterModule
]
})
export class ProductRoutingModule {}
In the AppMarketingPageProductComponent constructor
constructor( private route: ActivatedRoute ) {}
With these 2 I try to get the params within onNgInit function
this.route.params.subscribe( (params: Params) => {
console.log(params);
});
When I try to load the page I get an empty object. instead of "slug" or "slug" and "secondary" values key-value pairs.
The problem is that what I thought were child routes aren't really child routes so this
const routes: Routes = [
{
path: '',
component: AppMarketingPageProductComponent,
children: [
{ path: ':slug', component: AppMarketingPageProductComponent },
{ path: ':slug', component: AppMarketingPageProductComponent },
{ path: ':slug/:secondary', component: AppMarketingPageProductComponent },
]
}
];
needed to be changed to this
const routes: Routes = [
{ path: ':slug', component: AppMarketingPageProductComponent },
{ path: ':slug', component: AppMarketingPageProductComponent },
{ path: ':slug/:secondary', component: AppMarketingPageProductComponent },
];
now it works.

Ionic 4 navigate to tabs

I'm working on an Ionic 4 project, I've generated a tabs project.
What I want to do is create a Login page which is the default page.
When a user has signed in successfully I want to navigate to the tabs.
When I'm trying to do this I get the error:
Error: Cannot match any routes. URL Segment: 'tabs'
These are my routes:
const routes: Routes = [
{ path: '', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'Login', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'tabs', loadChildren: './tabs/tabs.module#TabsPageModule' },
];
In my Login Page I have a button as follows:
<ion-button expand="block" [href]="'tabs'" color="light" fill="outline">Sign in</ion-button>
When I generate a different page I am able to navigate to this page using the same way.
I was facing the same issue. I found a solution here. You need to add an additional route to your routes array.
const routes: Routes = [
{ path: '', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'Login', loadChildren: './login/login.module#LoginPageModule' },
{ path: 'tabs', loadChildren: './tabs/tabs.module#TabsPageModule' },
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' },
];
Step 1 : Add an additional route to tabs page in your app-routing.module.ts
{ path: 'app', loadChildren: './pages/tabs/tabs.module#TabsPageModule' }
Step 2 : Add the tabs route inside the tabs-routing.module.ts
const routes: Routes =[
{
path:'tabs',
component:TabsPage,
children:[
{
path : 'home',
outlet : 'home',
component : HomePage
},
{
path : 'me',
outlet : 'me',
component : MePage
}
]
}
];
Step 3 : Link to the tabs page
<ion-button href="app/tabs/(home:home)" routerDirection='root'>Tabs</ion-button>
I faced the same issue. My first page is 'Sign In' page by default. I wanted to navigate to tabs module after button click.
app-routing.module.ts:
import { NgModule } from '#angular/core';
import { PreloadAllModules, RouterModule, Routes } from '#angular/router';
const routes: Routes = [
{ path: 'app', loadChildren: './tabs/tabs.module#TabsPageModule' },
{ path: '', loadChildren: './sign-in/sign-in.module#SignInPageModule' },
{ path: 'search', loadChildren: './search/search.module#SearchPageModule' }
];
#NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
tabs.router.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { TabsPage } from './tabs.page';
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'home',
children: [
{
path: '',
loadChildren: '../home/home.module#HomePageModule'
}
]
},
{
path: 'my-requests',
children: [
{
path: '',
loadChildren: '../my-requests/my-requests.module#MyRequestPageModule'
}
]
},
{
path: 'add-request',
children: [
{
path: '',
loadChildren: '../add-request/add-request.module#AddRequestPageModule'
}
]
},
{
path: 'search',
children: [
{
path: '',
loadChildren: '../search/search.module#SearchPageModule'
}
]
},
{
path: 'profile',
children: [
{
path: '',
loadChildren: '../profile/profile.module#ProfilePageModule'
}
]
},
{
path: '',
redirectTo: '/tabs/home',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/tabs/home',
pathMatch: 'full'
}
];
#NgModule({
imports: [
RouterModule.forChild(routes)
],
exports: [RouterModule]
})
export class TabsPageRoutingModule {}
sign-in.module.ts:
....
const routes: Routes = [
{
path: "",
component: SignInPage
}
];
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes)
],
declarations: [SignInPage]
})
....
sign-in.page.html:
<ion-button (click)="navigateToProfile()">Sign In</ion-button>
sign-in.page.ts:
navigateToProfile(){
this.navController.navigateRoot(`app/tabs/home`);
}
Overall, my solution was:
adding one more path: 'app' in my root module app-routing.module
navigating to root with route with NavController. See here for more details, I found it here.