diff --git a/packages/astro/src/vite-plugin-astro-server/base.ts b/packages/astro/src/vite-plugin-astro-server/base.ts index 4fad19a2b7..e65c948c28 100644 --- a/packages/astro/src/vite-plugin-astro-server/base.ts +++ b/packages/astro/src/vite-plugin-astro-server/base.ts @@ -2,7 +2,7 @@ import type * as vite from 'vite'; import type { AstroSettings } from '../@types/astro'; import * as fs from 'fs'; -import { LogOptions } from '../core/logger/core.js'; +import { LogOptions, warn } from '../core/logger/core.js'; import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js'; import { log404 } from './common.js'; import { writeHtmlResponse } from './response.js'; @@ -13,7 +13,8 @@ export function baseMiddleware( ): vite.Connect.NextHandleFunction { const { config } = settings; const site = config.site ? new URL(config.base, config.site) : undefined; - const devRoot = site ? site.pathname : new URL(config.base, 'http://localhost').pathname; + const devRootURL = new URL(config.base, 'http://localhost'); + const devRoot = site ? site.pathname : devRootURL.pathname; return function devBaseMiddleware(req, res, next) { const url = req.url!; @@ -46,9 +47,12 @@ export function baseMiddleware( const publicPath = new URL('.' + req.url, config.publicDir); fs.stat(publicPath, (_err, stats) => { if (stats) { - log404(logging, pathname); - const html = subpathNotUsedTemplate(devRoot, pathname); - return writeHtmlResponse(res, 404, html); + const expectedLocation = new URL('.' + url, devRootURL).pathname; + warn(logging, 'dev', `Requests for items in your public folder must also include your base. ${url} should be ${expectedLocation}. Omitting the base will break in production.`); + res.writeHead(301, { + 'Location': expectedLocation + }); + res.end(); } else { next(); } diff --git a/packages/astro/test/units/dev/dev.test.js b/packages/astro/test/units/dev/dev.test.js index ad3fba650e..eddc14c5dd 100644 --- a/packages/astro/test/units/dev/dev.test.js +++ b/packages/astro/test/units/dev/dev.test.js @@ -187,7 +187,8 @@ describe('dev container', () => { container.handle(r.req, r.res); await r.done; - expect(r.res.statusCode).to.equal(404); + expect(r.res.statusCode).to.equal(301); + expect(r.res.getHeader('location')).to.equal('/sub/test.txt'); } ); });