diff --git a/src/client/app/router.ts b/src/client/app/router.ts index 0b3d523f..49f191a0 100644 --- a/src/client/app/router.ts +++ b/src/client/app/router.ts @@ -58,7 +58,7 @@ export function createRouter( let latestPendingPath: string | null = null - async function loadPage(href: string, scrollPosition = 0) { + async function loadPage(href: string, scrollPosition = 0, isRetry = false) { const targetLoc = new URL(href, fakeHost) const pendingPath = (latestPendingPath = targetLoc.pathname) try { @@ -106,6 +106,19 @@ export function createRouter( if (!err.message.match(/fetch/)) { console.error(err) } + + // retry on fetch fail: the page to hash map may have been invalidated + // because a new deploy happened while the page is open. Try to fetch + // the updated pageToHash map and fetch again. + if (!isRetry) { + try { + const res = await fetch(siteDataRef.value.base + 'hashmap.json') + ;(window as any).__VP_HASH_MAP__ = await res.json() + await loadPage(href, scrollPosition, true) + return + } catch (e) {} + } + if (latestPendingPath === pendingPath) { latestPendingPath = null route.path = pendingPath diff --git a/src/node/build/build.ts b/src/node/build/build.ts index 7ed05aea..6dd1d2b2 100644 --- a/src/node/build/build.ts +++ b/src/node/build/build.ts @@ -5,6 +5,7 @@ import { resolveConfig } from '../config' import { renderPage } from './render' import { OutputChunk, OutputAsset } from 'rollup' import ora from 'ora' +import path from 'path' export async function build( root: string, @@ -68,6 +69,13 @@ export async function build( spinner.stopAndPersist({ symbol: okMark }) + + // emit page hash map for the case where a user session is open + // when the site got redeployed (which invalidates current hash map) + fs.writeJSONSync( + path.join(siteConfig.outDir, 'hashmap.json'), + pageToHashMap + ) } finally { await fs.remove(siteConfig.tempDir) }