* Redesigned 404 page

* Update 5xx template

Co-authored-by: Isaac McFadyen <6243993+mcfadyeni@users.noreply.github.com>
This commit is contained in:
Drew Powers 2021-11-12 09:29:25 -07:00 committed by GitHub
parent 48ebbb80d4
commit 2b031acbd7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 176 additions and 70 deletions

View file

@ -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, {

View 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>`;
}

View 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>`;
}

View file

@ -0,0 +1,50 @@
/**
* CSS is exported as a string so the error pages:
* 1. dont need to resolve a deep internal CSS import
* 2. dont 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;
}
`;

View file

@ -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 didnt 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>
`;
}