This is a somewhat common issue in Inertia.js + Vue apps and is usually related to caching, key props, or how Vue manages its internal state between page transitions.
Possible root causes and solutions:
1. Component Keying Issues
If two different "pages" (i.e., Vue components returned by Inertia) render similar markup or share base components, Vue might be reusing the previous component instead of fully replacing it. This can lead to the DOM not updating as expected.
Quick fix: Use a unique :key prop on your page's root element or the main wrapper, typically using route or component name.
Example:
<template>
<div :key="$page.component">
<!-- Your page content -->
</div>
</template>
Or, if using named pages:
<template>
<div :key="$page.url">
<!-- Your page content -->
</div>
</template>
2. Inertia Progress Recovery
Sometimes, Inertia's progress events or Vue's transition lifecycle can be interrupted. Ensure you don't have manual navigation or cached state interfering with Inertia's back/forward support.
Check your main app mount in app.js:
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/inertia-vue3'
createInertiaApp({
// ...
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el)
},
})
Make sure you are not saving scroll positions or page states improperly.
3. Use the Inertia Link component
Instead of Vue Router's <router-link>, always use Inertia's <Link>:
<template>
<ul>
<li v-for="product in products" :key="product.id">
<Link :href="route('products.show', product.id)">
{{ product.name }}
</Link>
</li>
</ul>
</template>
4. Disable Persistent Layouts Temporarily
If you use "persistent layouts" (the pattern with layout: (h, page) => h(Layout, [page])), try disabling it for debugging, as it can cause child components to stay mounted and state to persist.
5. Debug with Inertia DevTools
Check the Inertia.js DevTools extension to see if the page visits are actually firing as expected.
Summary (Step-by-step):
- Make sure all your main pages have a unique root key (for example,
:key="$page.component").
- Confirm you're using
<Link> from Inertia for navigation.
- Check your Inertia/Vue
app.js for proper mounting.
- Disable persistent layouts for debugging.
- Watch the behavior with the DevTools.
Example Fix
Let's say Results.vue is your search results page and Show.vue is the product page.
In Results.vue:
<template>
<div :key="$page.url">
<Head :title="`Search results for ${query}`" />
<ul>
<li v-for="product in products" :key="product.id">
<Link :href="route('products.show', product.id)">
{{ product.name }}
</Link>
</li>
</ul>
</div>
</template>
This :key="$page.url" ensures Vue re-initializes when the route changes.
If after these steps the issue persists, please post your app initialization code and the route definitions for further debugging.