Skip to content

Commit 1edc6ef

Browse files
authored
Merge branch 'main' into package-code-import-links
2 parents f0056af + 59691eb commit 1edc6ef

4 files changed

Lines changed: 47 additions & 17 deletions

File tree

app/router.options.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { RouterConfig } from 'nuxt/schema'
2+
3+
export default {
4+
scrollBehavior(to, _from, savedPosition) {
5+
// If the browser has a saved position (e.g. back/forward navigation), restore it
6+
if (savedPosition) {
7+
return savedPosition
8+
}
9+
10+
// If navigating to a hash anchor, scroll to it
11+
if (to.hash) {
12+
return { el: to.hash, behavior: 'smooth' }
13+
}
14+
15+
// Otherwise, scroll to the top of the page
16+
return { left: 0, top: 0 }
17+
},
18+
} satisfies RouterConfig

knip.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const config: KnipConfig = {
44
workspaces: {
55
'.': {
66
entry: [
7+
'app/router.options.ts!',
78
'app/app.vue!',
89
'app/error.vue!',
910
'app/pages/**/*.vue!',

modules/isr-fallback.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export default defineNuxtModule({
1313
}
1414

1515
nuxt.hook('nitro:init', nitro => {
16+
const htmlFallback = 'spa.prerender-fallback.html'
17+
const jsonFallback = 'payload-fallback.json'
1618
nitro.hooks.hook('compiled', () => {
1719
const spaTemplate = readFileSync(nitro.options.output.publicDir + '/200.html', 'utf-8')
1820
for (const path of [
@@ -26,14 +28,10 @@ export default defineNuxtModule({
2628
'package/[org]/[name]/v/[version]',
2729
'',
2830
]) {
29-
const outputPath = resolve(
30-
nitro.options.output.serverDir,
31-
'..',
32-
path,
33-
'spa.prerender-fallback.html',
34-
)
31+
const outputPath = resolve(nitro.options.output.serverDir, '..', path, htmlFallback)
3532
mkdirSync(resolve(nitro.options.output.serverDir, '..', path), { recursive: true })
3633
writeFileSync(outputPath, spaTemplate)
34+
writeFileSync(outputPath.replace(htmlFallback, jsonFallback), '{}')
3735
}
3836
})
3937
})

nuxt.config.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export default defineNuxtConfig({
108108
'/api/registry/package-meta/**': { isr: 300 },
109109
'/:pkg/.well-known/skills/**': { isr: 3600 },
110110
'/:scope/:pkg/.well-known/skills/**': { isr: 3600 },
111-
'/__og-image__/**': { isr: getISRConfig(60) },
111+
'/__og-image__/**': getISRConfig(60),
112112
'/_avatar/**': { isr: 3600, proxy: 'https://www.gravatar.com/avatar/**' },
113113
'/opensearch.xml': { isr: true },
114114
'/oauth-client-metadata.json': { prerender: true },
@@ -123,10 +123,14 @@ export default defineNuxtConfig({
123123
},
124124
},
125125
// pages
126-
'/package/:name': { isr: getISRConfig(60, true) },
127-
'/package/:name/v/:version': { isr: getISRConfig(60, true) },
128-
'/package/:org/:name': { isr: getISRConfig(60, true) },
129-
'/package/:org/:name/v/:version': { isr: getISRConfig(60, true) },
126+
'/package/:name': getISRConfig(60, { fallback: 'html' }),
127+
'/package/:name/_payload.json': getISRConfig(60, { fallback: 'json' }),
128+
'/package/:name/v/:version': getISRConfig(60, { fallback: 'html' }),
129+
'/package/:name/v/:version/_payload.json': getISRConfig(60, { fallback: 'json' }),
130+
'/package/:org/:name': getISRConfig(60, { fallback: 'html' }),
131+
'/package/:org/:name/_payload.json': getISRConfig(60, { fallback: 'json' }),
132+
'/package/:org/:name/v/:version': getISRConfig(60, { fallback: 'html' }),
133+
'/package/:org/:name/v/:version/_payload.json': getISRConfig(60, { fallback: 'json' }),
130134
// infinite cache (versioned - doesn't change)
131135
'/package-code/**': { isr: true, cache: { maxAge: 365 * 24 * 60 * 60 } },
132136
'/package-docs/**': { isr: true, cache: { maxAge: 365 * 24 * 60 * 60 } },
@@ -314,14 +318,23 @@ export default defineNuxtConfig({
314318
},
315319
})
316320

317-
function getISRConfig(expirationSeconds: number, fallback = false) {
318-
if (fallback) {
321+
interface ISRConfigOptions {
322+
fallback?: 'html' | 'json'
323+
}
324+
function getISRConfig(expirationSeconds: number, options: ISRConfigOptions = {}) {
325+
if (options.fallback) {
319326
return {
320-
expiration: expirationSeconds,
321-
fallback: 'spa.prerender-fallback.html',
322-
} as { expiration: number }
327+
isr: {
328+
expiration: expirationSeconds,
329+
fallback:
330+
options.fallback === 'html' ? 'spa.prerender-fallback.html' : 'payload-fallback.json',
331+
initialHeaders: options.fallback === 'json' ? { 'content-type': 'application/json' } : {},
332+
} as { expiration: number },
333+
}
323334
}
324335
return {
325-
expiration: expirationSeconds,
336+
isr: {
337+
expiration: expirationSeconds,
338+
},
326339
}
327340
}

0 commit comments

Comments
 (0)