N
Nuxt3d ago
hajisky

Important! Can Sanity documents be used to generate and manage Nuxt Pages?

I have successfully accomplished this feat…sort of but I still see some issues that I wonder if anyone knows how to get over this. The pages are sanity documents with a pagePath or slug. For instance “/”, ”/about” I have a […slug] page which is assigned a sanity-page-middleware There are some instances where redirect data is included in the page data from sanity which is the sole reason why I’ve put this logic in a middleware In this middleware we, we use the useAsyncData in combination with the sanity client fetch with the key of the async data page being the pagePath or slug gotten from the route middleware. Now on the catch-all page I get the page data with the useNuxtData composable by passing the key as the pagePath The issues I get now is handling missing pages a simple A simple check after the page fetch call such as
if (!page.value) {
throw createError({
statusCode: 404,
statusMessage: "Page Not Found",
fatal: true,
});
}
if (!page.value) {
throw createError({
statusCode: 404,
statusMessage: "Page Not Found",
fatal: true,
});
}
One would imagine should work, and it actually does! Except that, as I’ve discovered, somehow Nuxt runs the entire middleware first without fetching any data or the data wasn’t awaited, so the page data would not exist and hence the createError runs. The second or third time around, it does it as expected. And this is my issue/question!! Am I approaching this correctly? Or is there another way around this? Is this way even the better way to handle this problem of running pages on sanity?
2 Replies
kapa.ai
kapa.ai3d ago
Hi @hajisky. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You can use external data sources like Sanity to generate and manage Nuxt pages by leveraging a catch-all route (e.g., pages/[...slug].vue) and fetching page data based on the route path. This approach is similar to the "document-driven mode" described for Nuxt Content, where you fetch content dynamically using the route and display it in your page component. For example:
<script lang="ts" setup>
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => {
// Replace with your Sanity fetch logic
return fetchSanityPage(route.path)
})
</script>

<template>
<div>
<ContentRenderer v-if="page" :value="page" />
</div>
</template>
<script lang="ts" setup>
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => {
// Replace with your Sanity fetch logic
return fetchSanityPage(route.path)
})
</script>

<template>
<div>
<ContentRenderer v-if="page" :value="page" />
</div>
</template>
This pattern is documented for Nuxt Content, but the same logic applies if you swap out the content fetching for your Sanity client logic. The key is to use a unique key for each page (such as the route path or slug) when calling useAsyncData, ensuring correct caching and hydration behavior, especially with features like shared prerender data enabled in Nuxt 3. This prevents issues where data for one page might be incorrectly reused for another if the key is not unique enough Implement Document Driven mode in v3 Shared Prerender Data. Handling 404s:
Your approach to throwing a 404 error when the page data is missing is correct and matches Nuxt's recommended pattern:
if (!page.value) {
throw createError({
statusCode: 404,
statusMessage: "Page Not Found",
fatal: true,
});
}
if (!page.value) {
throw createError({
statusCode: 404,
statusMessage: "Page Not Found",
fatal: true,
});
}
This is the standard way to handle missing data in Nuxt pages Route Validation. Middleware and Data Fetching Issues:
However, using useAsyncData inside middleware is not a documented or recommended pattern in the official Nuxt docs. Middleware is typically used for authentication, redirects, or route validation, not for fetching and providing page data. Data fetching is best handled directly in the page component using useAsyncData, as shown above. If you need to handle redirects based on fetched data, you can do so after fetching the data in the page component, or use route validation via definePageMeta({ validate }) for simple checks. If you fetch data in middleware and then try to access it in the page via useNuxtData, you may run into timing issues, as you described—Nuxt may not have awaited the data fetch before the middleware completes, leading to missing data on the first run. Recommended Approach: - Fetch your Sanity page data in the page component using useAsyncData with a unique key (the route path or slug). - Handle 404s directly after the fetch in the page component. - Use middleware only for logic that does not depend on asynchronous data fetching, or use route validation for simple checks. - If you need to redirect based on page data, perform the redirect in the page component after the data is available. Summary:
Your general approach is sound, but move the data fetching and error handling into the page component, not middleware. This will resolve the timing issues and align with Nuxt's best practices for dynamic, document-driven pages from external sources like Sanity. If you need more advanced control (e.g., for redirects), you can still perform those actions in the page component after the data is fetched. If you need further details on integrating Sanity specifically, the knowledge sources do not provide explicit examples, but the pattern for dynamic content sources is well established in the Nuxt ecosystem. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@399515691830476833> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?