Router replace changes behavior / stops working

Hello. I am essentially using buttons at the top of my app like tabs where each one does router.replace(). They work fine going to each other however when I go to one “tab” and then another page inside that tab which uses router.push() and then back to the root of that tab it does not like going to another tab. Its like it almost does push instead of replace.

Here is what the top buttons look like:

<ion-toolbar class="page-toolbar">
        <ion-buttons slot="start" v-if="showBack">
            <ion-back-button
                text=""
                :icon="arrowBack">
            </ion-back-button>
        </ion-buttons>

        <ion-buttons slot="start" v-if="!showBack">
            <ion-button v-bind:class="active === 'home' ? 'active' : ''" fill="clear" @click="router.replace('/home')">
                <ion-icon class="home"></ion-icon>
            </ion-button>
        </ion-buttons>

        <ion-buttons slot="primary" v-if="!showBack && $root.user">
            <ion-button v-bind:class="active === 'user-profile' ? 'active' : ''" fill="clear" @click="router.replace('/user-profile?root=true')">
                <ion-icon class="profile"></ion-icon>
            </ion-button>
            <ion-button fill="clear">
                <ion-icon class="settings"></ion-icon>
            </ion-button>
        </ion-buttons>

        <ion-buttons slot="primary" v-if="!showBack && !$root.user">
            <ion-button  @click="router.push('/login')" fill="clear">
                <ion-icon class="profile"></ion-icon>
            </ion-button>
        </ion-buttons>

        <ion-title></ion-title>
    </ion-toolbar>

So essentially starts on /home button/tab. Clicks on profile it does router.replace('/user-profile'). User then clicks on a link inside of the user profile and that does router.push('/build') which essentially pushes another page with a back button. Then click back and are taken back to the user profile. Then if they click Home it does router.replace('/home') but its treating it like a push not a replace. I can tell by the animation and it shows a back button and then I cannot go anywhere. Its fine if i click between the home and profile “tabs” but once I go into another sub page and go back it breaks. I have tried just about everything.

I have tried to use <router-link replace> instead of manually with the @click router replace but that did not change the behavior. I don’t know if this is an ionic issue or a vue issue.

Are all of your pages wrapped in an IonPage component? If not, you will get weird behavior. More info here.

Yes I double checked all that. It seems to work if I just make the “tabs” links but then it does natural page loading instead of SPA style loading.

Can you provide your route index file contents?

Not sure if I need to do something with child routes but theres cases where the user profile could be pushed from the home page as well…

import {createRouter, createWebHistory} from '@ionic/vue-router';
import {Storage} from "@capacitor/storage";

const routes = [
	{
		path: '/',
		redirect: '/home'
	},
	{
		path: '/home',
		component: () => import('@/views/Home.vue'),
		//meta: {requiresAuth: true}
	},

	{
		path: '/login',
		component: () => import('@/views/LoginHome.vue'),
		//meta: {requiresAuth: true}
	},

	{
		path: '/login/with-password',
		component: () => import('@/views/Login/LoginWithPassword.vue'),
		//meta: {requiresAuth: true}
	},

	// User profile
	{
		path: '/user-profile',
		component: () => import('@/views/UserProfile.vue'),
	},
	{
		path: '/user-profile/:username',
		component: () => import('@/views/UserProfile.vue'),
	},

	{
		path: '/add-new-build',
		component: () => import('@/views/BuildProfile/AddNewBuild.vue'),
		meta: {requiresAuth: true}
	},

	// Build Profile
	{
		path: '/build-profile/:id',
		component: () => import('@/views/BuildProfile.vue'),
	},

	{
		path: '/build-profile/:id/build-sheet-category/:categoryId/edit',
		component: () => import ('@/views/BuildProfile/EditBuildSheetCategory.vue'),
		meta: {requiresAuth: true}
	},
	{
		path: '/build-profile/:id/add-new-photo',
		component: () => import ('@/views/BuildProfile/AddNewPhoto.vue'),
		meta: {requiresAuth: true}
	},
	{
		path: '/build-profile/:id/add-new-build-sheet-category',
		component: () => import ('@/views/BuildProfile/AddNewBuildSheetCategory.vue'),
		meta: {requiresAuth: true}
	},

	{
		path: '/build-profile/:id/photos/:photoId',
		component: () => import('@/views/BuildProfile/ViewPhoto.vue'),
	},

];

const router = createRouter({
	history: createWebHistory(process.env.BASE_URL),
	routes
});

router.beforeEach((to, from, next) => {
	Storage.get({key: 'axles:userApiKey'}).then(user => {
		if (!user.value && to.matched.some(record => record.meta.requiresAuth)) {
			next({
				path: '/login',
				query: {redirect: to.fullPath}
			});
		} else {
			window.userToken = user.value;
			next();
		}
	});
});

export default router

I don’t see any obvious issues with your routes. Assuming you have an IonRouterOutlet somewhere? Probably App.vue?

Is there a reason you are not using the traditional Ion Tabs setup?

I unfortunately don’t know the inner workings of Ionic routing enough to give any other pointers. Hopefully one of the devs on the core team can help. Can you provide a sample project with the issue? Most likely they will ask for that.

A sample project would be helpful. Hard to say what the issue is without being able to reproduce the issue myself.

I ended up switching to tabs completely but I think the issue came down to how url hierarchy is forced. This might be more of a vue issue than anything.

1 Like