404 page (#1811)
* Redesigned 404 page * Update 5xx template Co-authored-by: Isaac McFadyen <6243993+mcfadyeni@users.noreply.github.com>
This commit is contained in:
parent
48ebbb80d4
commit
2b031acbd7
5 changed files with 176 additions and 70 deletions
|
@ -19,7 +19,8 @@ import { collectResources } from '../ssr/html.js';
|
|||
import { createRouteManifest, matchRoute } from '../ssr/routing.js';
|
||||
import { createVite } from '../create-vite.js';
|
||||
import * as msg from './messages.js';
|
||||
import { errorTemplate } from './template/error.js';
|
||||
import notFoundTemplate from './template/4xx.js';
|
||||
import serverErrorTemplate from './template/5xx.js';
|
||||
|
||||
export interface DevOptions {
|
||||
logging: LogOptions;
|
||||
|
@ -303,7 +304,7 @@ export class AstroDevServer {
|
|||
} catch (err: any) {
|
||||
this.viteServer.ws.send({ type: 'error', err });
|
||||
const statusCode = 500;
|
||||
const html = errorTemplate({
|
||||
const html = serverErrorTemplate({
|
||||
statusCode,
|
||||
title: 'Internal Error',
|
||||
tabTitle: '500: Error',
|
||||
|
@ -347,7 +348,7 @@ export class AstroDevServer {
|
|||
}
|
||||
// if not found, fall back to default template
|
||||
else {
|
||||
html = errorTemplate({ statusCode, title: 'Not found', tabTitle: '404: Not Found', message: pathname });
|
||||
html = notFoundTemplate({ statusCode, title: 'Not found', tabTitle: '404: Not Found', pathname });
|
||||
}
|
||||
info(this.logging, 'astro', msg.req({ url: pathname, statusCode, reqTime: performance.now() - reqStart }));
|
||||
res.writeHead(statusCode, {
|
||||
|
|
51
packages/astro/src/core/dev/template/4xx.ts
Normal file
51
packages/astro/src/core/dev/template/4xx.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
import { encode } from 'html-entities';
|
||||
import { baseCSS } from './css.js';
|
||||
interface ErrorTemplateOptions {
|
||||
/** a short description of the error */
|
||||
pathname: string;
|
||||
/** HTTP error code */
|
||||
statusCode?: number;
|
||||
/** HTML <title> */
|
||||
tabTitle: string;
|
||||
/** page title */
|
||||
title: string;
|
||||
}
|
||||
|
||||
/** Display all errors */
|
||||
export default function template({ title, pathname, statusCode = 404, tabTitle }: ErrorTemplateOptions): string {
|
||||
return `<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>${tabTitle}</title>
|
||||
<style>
|
||||
${baseCSS}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.statusCode {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.astro {
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="center">
|
||||
<svg class="astro" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z" fill="white"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z" fill="#ff5d01"></path></svg>
|
||||
<h1>${statusCode ? `<span class="statusCode">${statusCode}: </span> ` : ''}<span class="statusMessage">${title}</span></h1>
|
||||
<pre>Path: ${encode(pathname)}</pre>
|
||||
</main>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
71
packages/astro/src/core/dev/template/5xx.ts
Normal file
71
packages/astro/src/core/dev/template/5xx.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { encode } from 'html-entities';
|
||||
import { baseCSS } from './css.js';
|
||||
|
||||
interface ErrorTemplateOptions {
|
||||
/** a short description of the error */
|
||||
message: string;
|
||||
/** information about where the error occurred */
|
||||
stack?: string;
|
||||
/** HTTP error code */
|
||||
statusCode?: number;
|
||||
/** HTML <title> */
|
||||
tabTitle: string;
|
||||
/** page title */
|
||||
title: string;
|
||||
/** show user a URL for more info or action to take */
|
||||
url?: string;
|
||||
}
|
||||
|
||||
/** Display all errors */
|
||||
export default function template({ title, url, message, stack, statusCode, tabTitle }: ErrorTemplateOptions): string {
|
||||
let error = url ? message.replace(url, '') : message;
|
||||
return `<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>${tabTitle}</title>
|
||||
<style>
|
||||
${baseCSS}
|
||||
|
||||
.wrapper {
|
||||
max-width: 80rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.statusCode {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
header {
|
||||
margin-bottom: 3rem;
|
||||
margin-top: 4rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.astro {
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="wrapper">
|
||||
<header>
|
||||
<svg class="astro" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z" fill="white"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z" fill="#ff5d01"></path></svg>
|
||||
<h1>${statusCode ? `<span class="statusCode">${statusCode}: </span> ` : ''}<span class="statusMessage">${title}</span></h1>
|
||||
</header>
|
||||
<pre>${encode(error)}</pre>
|
||||
${url ? `<a target="_blank" href="${url}">${url}</a>` : ''}
|
||||
<pre>${encode(stack)}</pre>
|
||||
</main>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
50
packages/astro/src/core/dev/template/css.ts
Normal file
50
packages/astro/src/core/dev/template/css.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* CSS is exported as a string so the error pages:
|
||||
* 1. don’t need to resolve a deep internal CSS import
|
||||
* 2. don’t need external dependencies to render (they may be shown because of a dep!)
|
||||
*/
|
||||
|
||||
// Base CSS: shared CSS among pages
|
||||
export const baseCSS = `
|
||||
:root {
|
||||
--gray-10: hsl(258, 7%, 10%);
|
||||
--gray-20: hsl(258, 7%, 20%);
|
||||
--gray-30: hsl(258, 7%, 30%);
|
||||
--gray-40: hsl(258, 7%, 40%);
|
||||
--gray-50: hsl(258, 7%, 50%);
|
||||
--gray-60: hsl(258, 7%, 60%);
|
||||
--gray-70: hsl(258, 7%, 70%);
|
||||
--gray-80: hsl(258, 7%, 80%);
|
||||
--gray-90: hsl(258, 7%, 90%);
|
||||
--orange: #ff5d01;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--gray-10);
|
||||
color: var(--gray-80);
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 800;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
color:;
|
||||
font-size: 1.2em;
|
||||
margin-top: 0;
|
||||
max-width: 60em;
|
||||
}
|
||||
`;
|
|
@ -1,67 +0,0 @@
|
|||
import { encode } from 'html-entities';
|
||||
|
||||
interface ErrorTemplateOptions {
|
||||
/** a short description of the error */
|
||||
message: string;
|
||||
/** information about where the error occurred */
|
||||
stack?: string;
|
||||
/** HTTP error code */
|
||||
statusCode?: number;
|
||||
/** HTML <title> */
|
||||
tabTitle: string;
|
||||
/** page title */
|
||||
title: string;
|
||||
/** show user a URL for more info or action to take */
|
||||
url?: string;
|
||||
}
|
||||
|
||||
/** Display internal 404 page (if user didn’t provide one) */
|
||||
export function errorTemplate({ title, url, message, stack, statusCode, tabTitle }: ErrorTemplateOptions): string {
|
||||
let error = url ? message.replace(url, '') : message;
|
||||
return `<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>${tabTitle}</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #101010;
|
||||
color: #d0d0d0;
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
.wrapper {
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
a {
|
||||
color: #ff5d01;
|
||||
}
|
||||
h1 {
|
||||
font-weight: 800;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
pre {
|
||||
color: #999;
|
||||
font-size: 1.2em;
|
||||
margin-top: 0;
|
||||
max-width: 60em;
|
||||
}
|
||||
.status {
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="wrapper">
|
||||
<h1>${statusCode ? `<span class="statusCode">${statusCode}</span> ` : ''}${title}</h1>
|
||||
<pre><code>${encode(error)}</code></pre>
|
||||
${url ? `<a target="_blank" href="${url}">${url}</a>` : ''}
|
||||
<pre><code>${encode(stack)}</code></pre>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
}
|
Loading…
Reference in a new issue