Last active
August 26, 2024 03:50
-
-
Save u007/0fd4b01296b0bda43e0015397ed2d90c to your computer and use it in GitHub Desktop.
nuxt3 prerender on server side without reloading on frontend
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default defineNuxtRouteMiddleware((to, from) => { | |
if (import.meta.server) return | |
const nav = useNavStore(); | |
// console.log('middlwae client', nav.clientSide) | |
if (nav.clientSide) { | |
return; | |
} | |
setTimeout(() => { | |
nav.setClientSide(true); | |
}, 200) | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default defineNuxtConfig({ | |
//.... | |
hooks: { | |
'pages:extend'(pages) { | |
function setMiddleware(pages: NuxtPage[]) { | |
for (const page of pages) { | |
if (/* some condition */ true) { | |
page.meta ||= {} | |
// Note that this will override any middleware set in `definePageMeta` in the page | |
page.meta.middleware = ['client'] | |
} | |
if (page.children) { | |
setMiddleware(page.children) | |
} | |
} | |
} | |
setMiddleware(pages) | |
} | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<ProductsProductList /> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts" setup> | |
import superjson from 'superjson' | |
const $nav = useNavStore() | |
const sharedProductList = useState('productList', () => '') | |
// to support objectid | |
superjson.registerCustom<ObjectID, string>( | |
{ | |
isApplicable: (v): v is ObjectID => v instanceof ObjectID, | |
serialize: v => v.toHexString(), | |
deserialize: v => { | |
try { | |
return new ObjectID(v); | |
} catch (error) { | |
console.warn(`Invalid ObjectID: ${v}. Returning null.`); | |
return new ObjectID('000000000000000000000000'); | |
} | |
}, | |
}, | |
'objectid' | |
); | |
const loadProducsts = async() => { | |
// your async code to return list | |
} | |
const { data, pending: productsLoading, refresh } = await useAsyncData( | |
'products', | |
async () => { | |
if (typeof window !== 'undefined' && !$nav.clientSide) { | |
console.log('useAsyncData server only, skipped.') | |
return | |
} | |
console.log('useAsyncData runs...') | |
const [productsData, | |
// categoriesData | |
] = await Promise.allSettled([ | |
loadProducts(), | |
// loadCategories(), | |
]) | |
if (typeof window === 'undefined') { | |
// console.log('useAsyncData productsData', superjson.stringify(productsData.value)) | |
const productRes = superjson.stringify(productsData.value) | |
sharedProductList.value = productRes | |
} else { | |
// update it to makesure it does not show when transition to another list or page | |
sharedProductList.value = superjson.stringify({ total: 0, list: [] }) | |
} | |
// sharedCategoryList.value = superjson.stringify(categoriesData.value) | |
}, | |
{ | |
watch: [currentPage, categoryIds, props.search, props.categoryId, props.limit, props.showCategories], | |
deep: true, | |
server: true, | |
// server: true | |
}) | |
onMounted(() => { | |
// console.log('data? sharedProductList', sharedProductList.value) | |
const productRes = sharedProductList.value ? superjson.parse(sharedProductList.value) : { list: [], total: 0 } | |
total.value = productRes.total | |
productList.value = productRes.list | |
// run any client side data | |
loadCategories() | |
// why the hell useasyncdata does not reload when this component is rerendered | |
refresh() | |
allowLoadMore.value = true | |
}) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment