Skip to content

Commit

Permalink
Merge branch 'slash-404-hint' into trailing-magic
Browse files Browse the repository at this point in the history
  • Loading branch information
ascorbic committed Jan 16, 2025
2 parents 4fbf0f1 + 2c1c2c9 commit f8e74c1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/many-fans-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Returns a more helpful 404 page in dev if there is a mismatch in trailing slashes
13 changes: 10 additions & 3 deletions packages/astro/src/template/4xx.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { appendForwardSlash, removeTrailingForwardSlash } from '@astrojs/internal-helpers/path';
import { escape } from 'html-escaper';

interface ErrorTemplateOptions {
Expand Down Expand Up @@ -129,11 +130,17 @@ export function subpathNotUsedTemplate(base: string, pathname: string) {
});
}

export function notFoundTemplate(pathname: string, message = 'Not found') {
export function trailingSlashMismatchTemplate(pathname: string, trailingSlash: 'always' | 'never' | 'ignore') {
const corrected =
trailingSlash === 'always'
? appendForwardSlash(pathname)
: removeTrailingForwardSlash(pathname);
return template({
pathname,
statusCode: 404,
title: message,
tabTitle: `404: ${message}`,
title: 'Not found',
tabTitle: '404: Not Found',
body: `<p>Your site is configured with <code>trailingSlash</code> set to <code>${trailingSlash}</code>. Do you want to go to <a href="${corrected}">${corrected}</a> instead?</p>
<p>Come to our <a href="https://astro.build/chat">Discord</a> if you need help.</p>`,
});
}
15 changes: 14 additions & 1 deletion packages/astro/src/vite-plugin-astro-server/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ import path from 'node:path';
import {
appendForwardSlash,
collapseDuplicateTrailingSlashes,
hasFileExtension,
} from '@astrojs/internal-helpers/path';
import { bold } from 'kleur/colors';
import type { Logger } from '../core/logger/core.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
import notFoundTemplate, {
subpathNotUsedTemplate,
trailingSlashMismatchTemplate,
} from '../template/4xx.js';
import { writeHtmlResponse, writeRedirectResponse } from './response.js';

export function baseMiddleware(
Expand All @@ -21,6 +25,7 @@ export function baseMiddleware(
const devRootURL = new URL(config.base, 'http://localhost');
const devRoot = site ? site.pathname : devRootURL.pathname;
const devRootReplacement = devRoot.endsWith('/') ? '/' : '';
const { trailingSlash } = settings.config;

return function devBaseMiddleware(req, res, next) {
const url = req.url!;
Expand All @@ -36,6 +41,14 @@ export function baseMiddleware(
return next(e);
}

if (
(trailingSlash === 'never' && pathname.endsWith('/')) ||
(trailingSlash === 'always' && !pathname.endsWith('/') && !hasFileExtension(pathname))
) {
const html = trailingSlashMismatchTemplate(pathname, trailingSlash);
return writeHtmlResponse(res, 404, html);
}

if (pathname.startsWith(devRoot)) {
req.url = url.replace(devRoot, devRootReplacement);
return next();
Expand Down

0 comments on commit f8e74c1

Please sign in to comment.