nitro icon indicating copy to clipboard operation
nitro copied to clipboard

Nuxt ISR with Vercel

Open tsiotska opened this issue 1 year ago • 0 comments

Environment

Vercel "nuxt": "^3.15.4"

Reproduction

nuxt.config

  prerender: {
    routes: [
      '/community/bilovodska-gromada/events',
      '/community/bilovodska-gromada/events/centr-zhittyestiikosti-bilovodskoyi-tg-zaproshuye-ditok-molodshogo-shkilnogo-viku-z-mamami-do',
    ]
  },
  nitro: {
    preset: "vercel",
    vercel: {
      config: {
        bypassToken: process.env.VERCEL_BYPASS_TOKEN,
      },
    },
  },
 routeRules: {
    '/community/**/events': { isr: true },
    '/community/**/events/**': { isr: true }
 }

_root/api/revalidate not /server/routes/api/revalidate

import {isValidSignature, SIGNATURE_HEADER_NAME} from '@sanity/webhook'

async function readBody(readable) {
  const chunks = []
  for await (const chunk of readable) {
    chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)
  }
  return Buffer.concat(chunks).toString('utf8')
}

export default async function (req, res) {
  const body = await readBody(req)
  const signature = req.headers[SIGNATURE_HEADER_NAME]

  if (!(await isValidSignature(body, signature, secret))) {
    res.status(401).json({success: false, message: 'Invalid signature'})
    return
  }

  const {slug, ...} = JSON.parse(body)

  const pathsToRevalidate = []
  ...
  const results = await Promise.allSettled(
    pathsToRevalidate.map(async (path) => {
      try {
        const response = await fetch(`https://${projectName}.vercel.app${path}`, {
          method: 'GET',
          headers: {
            'x-prerender-revalidate': process.env.VERCEL_BYPASS_TOKEN,
          },
        })

        const html = await response.text()

        if (!response.ok) {
          console.error(`Failed to revalidate path "${path}"`, html)
          return {path, error: html}
        }

        console.log(`✅ Revalidated: ${path}`)
        return {path, revalidated: true, snippet: html.slice(0, 100)}
      } catch (err) {
        console.error(`❌ Error during revalidation for path "${path}"`, err)
        return {path, error: err.message}
      }
    })
  )

  return res.json({revalidated: pathsToRevalidate, results})
}

Describe the bug

Related to https://github.com/nitrojs/nitro/issues/889

The page is not revalidated on-demand. I followed documentation to enable ISR https://nitro.build/deploy/providers/vercel#on-demand-incremental-static-regeneration-isr.

  1. Set VERCEL_BYPASS_TOKEN in Vercel env vars.
  2. Defined Nuxt config with enabled 'vercel' preset and set bypassToken.
  3. Changed data and hit Vercel serverless /api/revalidate, sent 'x-prerender-revalidate': process.env.VERCEL_BYPASS_TOKEN and received positive response 200 with old page.
  4. Visiting site always show old page. Vercel ISR logs shows 0 Read and Write usage.

What I expected to receive on reload is certain rebuild page with new data, but apparently Nitro does not exactly rebuild page so I don't really understand If i can do what I want to.

Additional context

No response

Logs


tsiotska avatar Apr 17 '25 20:04 tsiotska