diff options
Diffstat (limited to 'packages/integrations/netlify')
6 files changed, 82 insertions, 4 deletions
diff --git a/packages/integrations/netlify/src/index.ts b/packages/integrations/netlify/src/index.ts index d6dcc353f..e634c4ecc 100644 --- a/packages/integrations/netlify/src/index.ts +++ b/packages/integrations/netlify/src/index.ts @@ -105,13 +105,14 @@ export default function netlifyIntegration( } } - async function writeSSRFunction() { + async function writeSSRFunction(notFoundContent?: string) { await writeFile( new URL('./ssr.mjs', ssrOutputDir()), ` import createSSRHandler from './entry.mjs'; export default createSSRHandler(${JSON.stringify({ cacheOnDemandPages: Boolean(integrationConfig?.cacheOnDemandPages), + notFoundContent, })}); export const config = { name: "Astro SSR", generator: "@astrojs/netlify@${packageVersion}", path: "/*", preferStatic: true }; ` @@ -300,7 +301,11 @@ export default function netlifyIntegration( logger.info('Emitted _redirects'); if (_config.output !== 'static') { - await writeSSRFunction(); + let notFoundContent = undefined; + try { + notFoundContent = await readFile(new URL('./404.html', dir), 'utf8'); + } catch {} + await writeSSRFunction(notFoundContent); logger.info('Generated SSR Function'); } diff --git a/packages/integrations/netlify/src/ssr-function.ts b/packages/integrations/netlify/src/ssr-function.ts index d0a963bde..33aea2717 100644 --- a/packages/integrations/netlify/src/ssr-function.ts +++ b/packages/integrations/netlify/src/ssr-function.ts @@ -13,11 +13,14 @@ const clientAddressSymbol = Symbol.for('astro.clientAddress'); export const createExports = (manifest: SSRManifest, _args: Args) => { const app = new App(manifest); - function createHandler(integrationConfig: { cacheOnDemandPages: boolean }) { + function createHandler(integrationConfig: { cacheOnDemandPages: boolean, notFoundContent?: string }) { return async function handler(request: Request, context: Context) { const routeData = app.match(request); - Reflect.set(request, clientAddressSymbol, context.ip); + if (!routeData && typeof integrationConfig.notFoundContent !== 'undefined') { + return new Response(integrationConfig.notFoundContent, { status: 404 }); + } + Reflect.set(request, clientAddressSymbol, context.ip); let locals: Record<string, unknown> = {}; const astroLocalsHeader = request.headers.get('x-astro-locals'); diff --git a/packages/integrations/netlify/test/functions/cookies.test.js b/packages/integrations/netlify/test/functions/cookies.test.js index ea8df7980..56a414d17 100644 --- a/packages/integrations/netlify/test/functions/cookies.test.js +++ b/packages/integrations/netlify/test/functions/cookies.test.js @@ -23,4 +23,24 @@ describe('Cookies', () => { expect(resp.headers.get('location')).to.equal('/'); expect(resp.headers.getSetCookie()).to.eql(['foo=foo; HttpOnly', 'bar=bar; HttpOnly']); }); + + it("renders dynamic 404 page", async () => { + const entryURL = new URL( + './fixtures/cookies/.netlify/functions-internal/ssr/ssr.mjs', + import.meta.url + ); + const { default: handler } = await import(entryURL); + const resp = await handler( + new Request('http://example.com/nonexistant-page', { + headers: { + "x-test": "bar" + } + }), + {} + ); + expect(resp.status).to.equal(404); + const text = await resp.text() + expect(text).to.contain("This is my custom 404 page"); + expect(text).to.contain("x-test: bar"); + }) }); diff --git a/packages/integrations/netlify/test/functions/fixtures/cookies/src/pages/404.astro b/packages/integrations/netlify/test/functions/fixtures/cookies/src/pages/404.astro new file mode 100644 index 000000000..9049fa0fb --- /dev/null +++ b/packages/integrations/netlify/test/functions/fixtures/cookies/src/pages/404.astro @@ -0,0 +1,7 @@ +--- +export const prerender = false +const header = Astro.request.headers.get("x-test") +--- + +<p>This is my custom 404 page</p> +<p>x-test: {header}</p>
\ No newline at end of file diff --git a/packages/integrations/netlify/test/functions/fixtures/redirects/src/pages/404.astro b/packages/integrations/netlify/test/functions/fixtures/redirects/src/pages/404.astro new file mode 100644 index 000000000..b9e3eda13 --- /dev/null +++ b/packages/integrations/netlify/test/functions/fixtures/redirects/src/pages/404.astro @@ -0,0 +1,5 @@ +--- +export const prerender = true +--- + +<p>This is my static 404 page</p>
\ No newline at end of file diff --git a/packages/integrations/netlify/test/functions/redirects.test.js b/packages/integrations/netlify/test/functions/redirects.test.js index 3cfa1cfd0..8c1b1fa2e 100644 --- a/packages/integrations/netlify/test/functions/redirects.test.js +++ b/packages/integrations/netlify/test/functions/redirects.test.js @@ -1,5 +1,6 @@ import { loadFixture } from '@astrojs/test-utils'; import { expect } from 'chai'; +import { createServer } from 'http'; describe('SSR - Redirects', () => { let fixture; @@ -25,4 +26,41 @@ describe('SSR - Redirects', () => { } expect(hasErrored).to.equal(true, 'this file should not exist'); }); + + it("renders static 404 page", async () => { + const entryURL = new URL( + './fixtures/redirects/.netlify/functions-internal/ssr/ssr.mjs', + import.meta.url + ); + const { default: handler } = await import(entryURL); + const resp = await handler( + new Request('http://example.com/nonexistant-page', ), + {} + ); + expect(resp.status).to.equal(404); + const text = await resp.text() + expect(text).to.contain("This is my static 404 page"); + }) + + it('does not pass through 404 request', async () => { + let testServerCalls = 0 + const testServer = createServer((req, res) => { + testServerCalls++ + res.writeHead(200) + res.end() + }) + testServer.listen(5678) + const entryURL = new URL( + './fixtures/redirects/.netlify/functions-internal/ssr/ssr.mjs', + import.meta.url + ); + const { default: handler } = await import(entryURL); + const resp = await handler( + new Request('http://localhost:5678/nonexistant-page'), + {} + ); + expect(resp.status).to.equal(404); + expect(testServerCalls).to.equal(0) + testServer.close() + }); }); |