diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts index a71d6d788..00461c9bb 100644 --- a/packages/astro/src/vite-plugin-astro-server/index.ts +++ b/packages/astro/src/vite-plugin-astro-server/index.ts @@ -166,8 +166,10 @@ async function handle500Response( } function getCustom404Route(config: AstroConfig, manifest: ManifestData) { + // For Windows compat, use relative page paths to match the 404 route const relPages = resolvePages(config).href.replace(config.root.href, ''); - return manifest.routes.find((r) => r.component === appendForwardSlash(relPages) + '404.astro'); + const pattern = new RegExp(`${appendForwardSlash(relPages)}404.(astro|md)`); + return manifest.routes.find((r) => r.component.match(pattern)); } function log404(logging: LogOptions, pathname: string) { diff --git a/packages/astro/test/custom-404-md.test.js b/packages/astro/test/custom-404-md.test.js new file mode 100644 index 000000000..69eddb26b --- /dev/null +++ b/packages/astro/test/custom-404-md.test.js @@ -0,0 +1,40 @@ +import { expect } from 'chai'; +import * as cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; + +describe('Custom 404 Markdown', () => { + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/custom-404-md/', + }); + }); + + describe('dev', () => { + let devServer; + let $; + + before(async () => { + devServer = await fixture.startDevServer(); + }); + + after(async () => { + await devServer.stop(); + }); + + it('renders /', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + $ = cheerio.load(html); + + expect($('h1').text()).to.equal('Home'); + }); + + it('renders 404 for /abc', async () => { + const html = await fixture.fetch('/a').then((res) => res.text()); + $ = cheerio.load(html); + + expect($('h1').text()).to.equal('Page not found'); + }); + }); +}); diff --git a/packages/astro/test/fixtures/custom-404-md/astro.config.mjs b/packages/astro/test/fixtures/custom-404-md/astro.config.mjs new file mode 100644 index 000000000..882e6515a --- /dev/null +++ b/packages/astro/test/fixtures/custom-404-md/astro.config.mjs @@ -0,0 +1,4 @@ +import { defineConfig } from 'astro/config'; + +// https://astro.build/config +export default defineConfig({}); diff --git a/packages/astro/test/fixtures/custom-404-md/package.json b/packages/astro/test/fixtures/custom-404-md/package.json new file mode 100644 index 000000000..4f6a0b25f --- /dev/null +++ b/packages/astro/test/fixtures/custom-404-md/package.json @@ -0,0 +1,8 @@ +{ + "name": "@test/custom-404-md", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/custom-404-md/src/layouts/Base.astro b/packages/astro/test/fixtures/custom-404-md/src/layouts/Base.astro new file mode 100644 index 000000000..971e10ff1 --- /dev/null +++ b/packages/astro/test/fixtures/custom-404-md/src/layouts/Base.astro @@ -0,0 +1,12 @@ +--- +const { content } = Astro.props; +--- + + +
+