vercel-builder
vercel-builder copied to clipboard
Serverless Pre-Rendering (SPR)
Hey
Seems like recently introduced Serverless Pre-Rendering (SPR) feature fits perfectly to nuxt, But I feel a little bit confused about configuration. How can I use that?
Where I need define res header cache?
Would be cool to get some expanded docs. Thanks!
Okey. I made it:
import generateETag from 'etag'
import axios from 'axios'
export default {
async asyncData ({ res }) {
let { data } = await axios.get(api)
const etag = await generateETag(JSON.stringify(data))
if (res) {
res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate')
res.setHeader("X-version", etag)
}
return { data: data, etag: etag }
},
mounted () {
fetch(window.location, {
headers: {
pragma: "no-cache"
}
}).then(res => {
if (res.ok && res.headers.get("x-version") !== this.etag) {
window.location.reload()
}
})
}
}
Also you need configure nuxt.config and set fs to 'empty' for properly building process in now-cloud (required for etag generator)
build: {
extend (config, { isDev, isClient }) {
config.node = {
fs: 'empty'
}
}
}
Probably not the most elegant solution, but it works.
@MarvinMiles Nice POC. Something we can do for improvement is moving etag
generation logic out of pages into SSR handler. I plan to make a community module for page-level caching. It should also operate in headers-only
mode that adds now's so-called SPR support.
Hey @pi0 @MarvinMiles glad you are talking about this. Does your solution work for you ? Although it's fine locally, when I deploy to now, I still get "public, max-age=0, must-revalidate" I've tried setting the header response as above, and also in server middleware. I can only guess that the header is being set prior to this somehow. Don't suppose either of you have any thoughts ?
@MarvinMiles Now SPR v2 is about to land - e.g. https://github.com/zeit/now/pull/3067
Nuxt v2.9 brought new cool feature that related to SPR use case: $nuxt.refresh(). $nuxt.refresh() can refresh page data reactively without actually reloading i.e rerendering the page like window.location.reload() do. Useful in case etag doesn't matches.
P.S. Still feel myself uncomfortable to manually manage etag logic.
I used a server middleware that set the following header to create a simple implementation of SPR that caches for 30 seconds.
module.exports = function (req, res, next) {
res.setHeader('Cache-Control', 's-maxage=30, stale-while-revalidate')
next()
}
👀
Something is coming: https://github.com/pi0/nuxt-swr-cache 🤗
@MarvinMiles I don’t quite get the SWR thing, does it relate to Now/Vercel SPR in any way or is it a try to get it without vendor lock-in?
@appinteractive Correct. 'stale-while-revalidate'
cache strategy isn't a Vercel`s invention. So making nuxt module to handle it without vendor lock-in makes sense.
BTW https://github.com/vercel/swr serves for another purpose. It handles fetching page data on client or server side while SPR handles cache of rendered HTML output only on server side.