N
Nuxt5w ago
Markeem

How to use KeepAlive properly

I have a couple pages that need to be kept alive. Even though I figured it out, I still wonder if thats the way it is supposed to be. I have the following pages overview/invoices.vue ( name prop = Overview-Invoices) and overview/items.vue ( name prop = Overview-Items). The only way it works reliably currently with the following code within my app.vue file:
<NuxtLayout class="font-inter relative">

<NuxtPage :keepalive="{include: ['invoices', 'items']}" />

</NuxtLayout>
<NuxtLayout class="font-inter relative">

<NuxtPage :keepalive="{include: ['invoices', 'items']}" />

</NuxtLayout>
It does not work using the name property defined in definePageMeta ( Overview-Invoices and Overview-Items). It also doesnt really work when setting keepalive=true within the definePageMeta function for both pages. The Navigation becomes really buggy doing this. Could someone explain to me how it is supposed to work exactly ? Because the current way seems weird to me. Why is the name prop not accepted and also there could be an issue with duplicate naming due to the folder routing ?
8 Replies
kapa.ai
kapa.ai5w ago
Hi @Markeem. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You're right to be cautious—using <KeepAlive> with Nuxt's file-based routing and auto-imported pages can be confusing, especially regarding how component names are generated and matched. How KeepAlive Works in Nuxt - By default, Nuxt wraps your page in Vue's <KeepAlive> if you set keepalive: true in definePageMeta or use the keepalive prop on <NuxtPage>. - The include/exclude arrays for <KeepAlive> match component names. In Nuxt, these names are auto-generated based on the file and folder structure, and may not always match what you expect, especially if you use nested folders or custom names in definePageMeta [NuxtPage API]. Component Name Matching - The component name used by <KeepAlive> is not the name you set in definePageMeta. Instead, it's auto-generated by Nuxt based on the file path. For example, pages/overview/invoices.vue becomes OverviewInvoices (or overview-invoices in kebab-case, depending on context) [Normalized Component Names]. - If you want to use the include prop, you must use the normalized component names as Nuxt generates them, not the custom name you set in definePageMeta. Why keepalive: true in definePageMeta Can Be Buggy - Setting keepalive: true in definePageMeta wraps each page in <KeepAlive>, but if you have nested routes or complex navigation, this can lead to unexpected cache behavior or bugs, especially if you don't control the cache keys or include/exclude lists precisely [Special Metadata]. - For more granular control, it's recommended to use the keepalive prop on <NuxtPage> in your layout or app.vue, as you did. Best Practice - Use the normalized component names in your include/exclude arrays. - Do not rely on the name property in definePageMeta for <KeepAlive> matching. - If you want to avoid issues with array recreation (which can cause cache resets), define your include/exclude arrays in <script setup> and reference them in your template, like this:
<script setup lang="ts">
const include = ['OverviewInvoices', 'OverviewItems']
</script>

<template>
<NuxtLayout>
<NuxtPage :keepalive="{ include }" />
</NuxtLayout>
</template>
<script setup lang="ts">
const include = ['OverviewInvoices', 'OverviewItems']
</script>

<template>
<NuxtLayout>
<NuxtPage :keepalive="{ include }" />
</NuxtLayout>
</template>
This approach prevents unnecessary cache pruning and ensures stable behavior [GitHub PR #30807]. Summary - Use the normalized component names (as Nuxt generates them from the file path) for <KeepAlive>'s include/exclude. - Setting keepalive: true in definePageMeta is fine for simple cases, but for more control, use the prop on <NuxtPage>. - The name in definePageMeta is for routing, not for <KeepAlive> matching. If you want to check the actual component names, you can inspect them in Vue DevTools or log them in your app. If you still experience buggy navigation, ensure you are not recreating the include/exclude arrays on every render, as this can cause <KeepAlive> to reset its cache [GitHub PR #30807]. Let me know if you need help determining the exact normalized names for your pages! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5w ago
<@810970873011896341> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Markeem
MarkeemOP5w ago
@kapa.ai is the issue related to the fact that maybe the normalized component names dont apply to pages in nuxt 3/4 ?
kapa.ai
kapa.ai5w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- No, the issue is not that normalized component names don't apply to pages in Nuxt 3/4. In fact, starting with Nuxt 3 and continuing in Nuxt 4, Nuxt introduced the experimental.normalizeComponentNames feature, which ensures that auto-generated Vue component names (including for pages) match the full component name you would use to auto-import the component. This means that for a page like pages/overview/invoices.vue, the normalized name would be OverviewInvoices, and this is the name you should use in the include or exclude arrays for <KeepAlive> [Normalized Component Names][Normalized Component Names 4.x]. If you have not explicitly disabled this feature in your nuxt.config.ts, normalized component names do apply to pages. If you want to ensure this behavior, you can set:
export default defineNuxtConfig({
experimental: {
normalizeComponentNames: true,
},
})
export default defineNuxtConfig({
experimental: {
normalizeComponentNames: true,
},
})
So, the issue is not that normalized names don't apply to pages, but rather that you must use the correct normalized names (as generated by Nuxt) in your <KeepAlive> configuration. If you use a different name (such as a custom name in definePageMeta), <KeepAlive> will not match the component correctly [Going Further: Experimental Features][Going Further: Experimental Features 4.x]. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5w ago
<@810970873011896341> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Markeem
MarkeemOP5w ago
@kapa.ai I already did use the normalized names according to the schema. But when looking for the page in the devtools I can only see the last part of the route as component/page name ( invoices and items)
kapa.ai
kapa.ai5w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the official Nuxt documentation, when experimental.normalizeComponentNames is enabled (which is the default in recent Nuxt 3 and 4 versions), Nuxt should generate component names that match the full path-based name (e.g., OverviewInvoices for pages/overview/invoices.vue). This is the name you should use for <KeepAlive>'s include/exclude props [Normalized Component Names][Experimental Features]. However, if you are seeing only the last part of the route (e.g., invoices or items) as the component/page name in Vue DevTools, this suggests that either: 1. The normalizeComponentNames feature is not enabled in your project, or
2. There is a mismatch between the expected normalized name and what is actually being generated or displayed. The documentation explicitly states that, by default, Vue assigns the component name based on the filename (e.g., invoices), and only with normalizeComponentNames enabled will it use the full path-based name (e.g., OverviewInvoices). If you want to ensure the normalized names are used, you should explicitly set in your nuxt.config.ts:
export default defineNuxtConfig({
experimental: {
normalizeComponentNames: true,
},
})
export default defineNuxtConfig({
experimental: {
normalizeComponentNames: true,
},
})
[Experimental Features] If you have already set this and still see only the last segment in DevTools, the knowledge sources do not provide further troubleshooting steps or explanations for this discrepancy. It may be a limitation or a bug not covered in the current documentation. Summary:
- With normalizeComponentNames enabled, you should see full path-based names. - If you only see the last segment, double-check your config. - If the config is correct and the issue persists, the knowledge sources do not provide more details on this behavior. If you need further help, you may want to check for open issues or discussions in the Nuxt repository, as this specific DevTools display issue is not fully addressed in the provided documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5w ago
<@810970873011896341> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?