nuxt
nuxt copied to clipboard
NuxtLoadingIndicator gets stuck on page with different layout and async setup
Environment
- Operating System: Windows_NT
- Node Version: v18.17.1
- Nuxt Version: 3.10.2
- CLI Version: 3.10.1
- Nitro Version: -
- Package Manager: [email protected]
- Builder: -
- User Config: devtools, modules, routeRules
- Runtime Modules: @nuxtjs/[email protected]
- Build Modules: -
Reproduction
https://stackblitz.com/edit/github-uqxt1s
Describe the bug
When using NuxtLoadingIndicator, an issue arises when navigating to a page with a different layout that contains an asynchronous operation within the setup function. In these specific cases, the loading indicator gets stuck and fails to disappear after the page has loaded.
On my production site, when this bug occurs, it also causes the page (newly switched layout) to become unscrollable. However I couldn't reproduce it but i feel it is somehow connected.
Additional context
No response
Logs
No response
@tberk Thanks for the reproduction! I am also seeing this issue but didn't know the exact reason.
Here is my temp workaround for this issue.
app.vue:
<script setup lang="ts">
const { finish: finishNuxtLoading } = useLoadingIndicator()
finishNuxtLoading()
if (process.client) {
finishNuxtLoading()
}
</script>
<template>
<NuxtLayout>
<div>
<NuxtLoadingIndicator color="#262626" />
<NuxtPage />
</div>
</NuxtLayout>
</template>
Moved<NuxtLoadingIndicator> out of the <NuxtLayout>
<template>
<NuxtLoadingIndicator :throttle="0" :height="10" />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
I have the same problem but use a setup with page templates using different layouts. @kingychiu solution works but it also, at least on my end, doesn't show the loading indicator at all after first time navigating between different layouts.
My solution for now is to only add <NuxtLoadingIndicator /> on the default layout, not ideal but since it's used for most pages in my setup it will have to do.
<template>
<NuxtLoadingIndicator />
<div>
<Header />
<main id="main">
<slot />
</main>
<Footer />
</div>
</template>
What I've found is that placing the loading indicator in app.vue, so that it isn't remounted with every layout change, solves all these issues.
This is definitely the solution @CernyMatej. In my use case, page templates with different layouts, all I had to do was to create app.vue and add the loading indicator there.
<template>
<NuxtLoadingIndicator />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
On each page that is not using the default layout just add:
definePageMeta({
layout: 'custom',
})
And make sure to remove <NuxtLoadingIndicator /> from the layouts.
To move the <NuxtLoadingIndicator /> to App.vue made the /pages file be rendered twice!
<template>
<NuxtLoadingIndicator :color="false" :height="3" />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
To fix that, I just needed to move it to the end of the template:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<NuxtLoadingIndicator :color="false" :height="3" />
</template>
In my case, after throwing full page error, when I trigger clearError({ redirect: '/' }) , the home page successfully appears but the loading indicator remains stuck.
In my case, I have just created app.vue file and take the <NuxtLoadingIndicator /> out of the <NuxtLayout />:
<template>
<div>
<NuxtLoadingIndicator />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</template>