content icon indicating copy to clipboard operation
content copied to clipboard

[v3] Layout duplication if no hard-reload

Open gitFoxCode opened this issue 11 months ago • 3 comments

Environment



Version

v3

Reproduction

https://stackblitz.com/edit/github-463w2fki?file=app%2Fapp.vue

Description

I'm migrating my project from Nuxt Content v2 to v3, and almost every page in my project uses a layout. Unfortunately, there's an issue with this: when navigating to another subpage (without a hard reload), the layout glitches, sometimes duplicates, and so on.

In the reproduction, I've created code that demonstrates this behavior.

To check the layout on each page, I'm forced to create a collection that includes all possible .md files:

content: defineCollection({
    type: 'page',
    source: '*/**.md'
}),

so that I can use:

const route = useRoute()
const { data: page } = await useAsyncData(route.path, async () => {
  return queryCollection('content').path(route.path).first()
})

so that I can later use:

<NuxtLayout :name="page?.meta?.layout || 'default'">
    <NuxtPage />
</NuxtLayout>

After navigating to /getting-started/usage and then clicking a button that redirects to /getting-started/test, the layout does not update. However, if I do a hard refresh, it loads correctly.

How should I properly handle layouts in this case?

And - is there an alternative approach to the Document-Driven mode that doesn’t require creating a collection of ALL md files? Wouldn't this duplicate content in the database? I’m using this collection only for [..slug].vue to display the correct page based on the URL.

What can be done about this? Maybe I’m using the new features incorrectly, or is this a bug?

PS. how can I prevent these types of issues in the future, where a hard refresh behaves completely differently from a regular navigation—especially during development?

Additional context

No response

Logs


gitFoxCode avatar Feb 07 '25 11:02 gitFoxCode

This is not related to Nuxt Content, you are using route.path as the key for useAsyncData both in [...slug].vue and app.vue. But they return a different structure. This different structure and the same key cause conflict and therefore invalid layout.

in app.vue if you print {{ page }} you can see that after the page load it will print { page: { id: .... } }. instead of { id: ....}

farnabaz avatar Feb 07 '25 12:02 farnabaz

@farnabaz Thanks a lot! I didn’t notice the duplicated key names - that was indeed the problem

gitFoxCode avatar Feb 07 '25 12:02 gitFoxCode

@farnabaz I closed it too early, assuming that must be the issue, but after testing it with various other keys like ${route.path}-key123, pure strings, and so on, the page still behaves the same way after running nuxt generate, etc. The page acts as if <script setup> in app.vue doesn’t run at all after navigating to another page. This would make some sense in general, if not for the fact that I don’t know how to properly change the layout in [...slug].vue, where I don’t have access to <NuxtLayout>, and I can't use useMeta with await useAsyncData

gitFoxCode avatar Feb 07 '25 15:02 gitFoxCode