diff --git a/.changeset/stale-pandas-count.md b/.changeset/stale-pandas-count.md new file mode 100644 index 000000000000..b67de833cf80 --- /dev/null +++ b/.changeset/stale-pandas-count.md @@ -0,0 +1,5 @@ +--- +"@astrojs/vercel": patch +--- + +Fixes an issue where the serverless function could not respond with a prerendered 404 page. diff --git a/packages/integrations/vercel/src/serverless/adapter.ts b/packages/integrations/vercel/src/serverless/adapter.ts index dd07e723b644..db7f428051e1 100644 --- a/packages/integrations/vercel/src/serverless/adapter.ts +++ b/packages/integrations/vercel/src/serverless/adapter.ts @@ -287,9 +287,15 @@ You can set functionPerRoute: false to prevent surpassing the limit.` excludeFiles, maxDuration, }); - routeDefinitions.push({ src: '/.*', dest: 'render' }); + for (const route of routes) { + if (route.prerender) continue + routeDefinitions.push({ + src: route.pattern.source, + dest: 'render', + }) + } } - + const fourOhFourRoute = routes.find((route) => route.pathname === '/404'); // Output configuration // https://vercel.com/docs/build-output-api/v3#build-output-configuration await writeJson(new URL(`./config.json`, _config.outDir), { @@ -303,6 +309,11 @@ You can set functionPerRoute: false to prevent surpassing the limit.` }, { handle: 'filesystem' }, ...routeDefinitions, + ...fourOhFourRoute ? [{ + src: '/.*', + dest: fourOhFourRoute.prerender ? '/404.html' : 'render', + status: 404, + }] : [], ], ...(imageService || imagesConfig ? { diff --git a/packages/integrations/vercel/test/fixtures/prerendered-error-pages/astro.config.mjs b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/astro.config.mjs new file mode 100644 index 000000000000..b3f5bd362bae --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; +import vercel from '@astrojs/vercel/serverless'; + +export default defineConfig({ + output: 'server', + adapter: vercel() +}); diff --git a/packages/integrations/vercel/test/fixtures/prerendered-error-pages/package.json b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/package.json new file mode 100644 index 000000000000..5cfc0e24c44d --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/astro-vercel-prerendered-error-pages", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/vercel": "workspace:*", + "astro": "workspace:*" + } +} diff --git a/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/404.astro b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/404.astro new file mode 100644 index 000000000000..162ff90b6820 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/404.astro @@ -0,0 +1,4 @@ +--- +export const prerender = true +--- +

404

diff --git a/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/one.astro b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/one.astro new file mode 100644 index 000000000000..0c7fb90a735e --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/one.astro @@ -0,0 +1,8 @@ + + + One + + +

One

+ + diff --git a/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/two.astro b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/two.astro new file mode 100644 index 000000000000..e7ba9910e2a6 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/prerendered-error-pages/src/pages/two.astro @@ -0,0 +1,8 @@ + + + Two + + +

Two

+ + diff --git a/packages/integrations/vercel/test/prerendered-error-pages.test.js b/packages/integrations/vercel/test/prerendered-error-pages.test.js new file mode 100644 index 000000000000..9085662238d8 --- /dev/null +++ b/packages/integrations/vercel/test/prerendered-error-pages.test.js @@ -0,0 +1,23 @@ +import { loadFixture } from './test-utils.js'; +import { expect } from 'chai'; + +describe('prerendered error pages routing', () => { + /** @type {import('./test-utils.js').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/prerendered-error-pages/', + }); + await fixture.build(); + }); + + it('falls back to 404.html', async () => { + const deploymentConfig = JSON.parse(await fixture.readFile('../.vercel/output/config.json')); + expect(deploymentConfig.routes.at(-1)).to.deep.include({ + src: '/.*', + dest: '/404.html', + status: 404, + }); + }); +}); diff --git a/packages/integrations/vercel/test/static.test.js b/packages/integrations/vercel/test/static.test.js index fc97e46ad7e9..a3d0ea738272 100644 --- a/packages/integrations/vercel/test/static.test.js +++ b/packages/integrations/vercel/test/static.test.js @@ -1,7 +1,7 @@ import { loadFixture } from './test-utils.js'; import { expect } from 'chai'; -describe('maxDuration', () => { +describe('static routing', () => { /** @type {import('./test-utils.js').Fixture} */ let fixture; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7dd02558ad6a..69b6abd703bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4749,6 +4749,15 @@ importers: specifier: workspace:* version: link:../../../../../astro + packages/integrations/vercel/test/fixtures/prerendered-error-pages: + dependencies: + '@astrojs/vercel': + specifier: workspace:* + version: link:../../.. + astro: + specifier: workspace:* + version: link:../../../../../astro + packages/integrations/vercel/test/fixtures/redirects: dependencies: '@astrojs/vercel':