Adds prerendered, JS-less, self-contained error pages for nginx error_page use — served directly from /var/www/errors/ when the SvelteKit upstream is unreachable or any nginx-originated 4xx/5xx fires (including the catch-all default_server for unknown hosts). - /errors/[status] (DE default) + /errors/en/[status] (EN), each with a header language toggle linking absolute to bocken.org so the switch works even on unknown-host fallbacks. - httpStatus param matcher restricts entries to 401/403/404/500/ 502/503/504; entries() drives prerender output. - generate-error-quotes.ts looks up curated bilingual references in the existing allioli/drb TSV bibles at prebuild time and writes src/lib/data/errorQuotes.json. - build-error-page.ts (postbuild) inlines all CSS, strips module preloads/scripts, rewrites the home-link to canonical https URL, and emits .html + .gz + .br per status under build/client/errors. - deploy.sh syncs build/client/errors → /var/www/errors with http:http ownership for nginx access.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"401": {
|
||||
"de": {
|
||||
"text": "Bittet, und es wird euch gegeben werden; suchet, und ihr werdet finden; klopfet an, und es wird euch aufgetan werden",
|
||||
"reference": "Mt 7,7"
|
||||
},
|
||||
"en": {
|
||||
"text": "Ask, and it shall be given you: seek, and you shall find: knock, and it shall be opened to you.",
|
||||
"reference": "Mt 7:7"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"de": {
|
||||
"text": "Wie eng ist die Pforte, und wie schmal der Weg, der zum Leben führt; und wenige sind, die ihn finden!",
|
||||
"reference": "Mt 7,14"
|
||||
},
|
||||
"en": {
|
||||
"text": "How narrow is the gate, and strait is the way that leadeth to life: and few there are that find it!",
|
||||
"reference": "Mt 7:14"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"de": {
|
||||
"text": "Denn ein jeder, der bittet, der empfängt; und wer suchet, findet; und dem, der anklopft, wird aufgetan werden.",
|
||||
"reference": "Mt 7,8"
|
||||
},
|
||||
"en": {
|
||||
"text": "For every one that asketh, receiveth: and he that seeketh, findeth: and to him that knocketh, it shall be opened.",
|
||||
"reference": "Mt 7:8"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"de": {
|
||||
"text": "Wir haben aber diesen Schatz in irdenen Gefäßen, damit die Überschwenglichkeit der Kraft nicht uns, sondern Gott beigemessen werde.",
|
||||
"reference": "2Kor 4,7"
|
||||
},
|
||||
"en": {
|
||||
"text": "But we have this treasure in earthen vessels, that the excellency may be of the power of God and not of us.",
|
||||
"reference": "2Cor 4:7"
|
||||
}
|
||||
},
|
||||
"502": {
|
||||
"de": {
|
||||
"text": "Darum ward ihr Name Babel genannt, weil daselbst sie Sprache der ganzen Menschheit verwirrt ward; und von da zerstreute sie der Herr über alle Lande.",
|
||||
"reference": "1Mo 11,9"
|
||||
},
|
||||
"en": {
|
||||
"text": "And therefore the name thereof was called Babel, because there the language of the whole earth was confounded: and from thence the Lord scattered them abroad upon the face of all countries.",
|
||||
"reference": "Gn 11:9"
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"de": {
|
||||
"text": "Sei dem Herrn untergeben und bete zu ihm. Ereifere dich nicht über den, der glücklich ist auf seinem Wege, über den Mann, der Unrecht tut.",
|
||||
"reference": "Ps 37,7"
|
||||
},
|
||||
"en": {
|
||||
"text": "I am become miserable, and am bowed down even to the end: I walked sorrowful all the day long.",
|
||||
"reference": "Ps 37:7"
|
||||
}
|
||||
},
|
||||
"504": {
|
||||
"de": {
|
||||
"text": "die aber auf den Herrn hoffen, erneuern ihre Kraft, heben ihre Schwingen gleich Adlern, laufen und werden nicht müde, schreiten voran und werden nicht matt.",
|
||||
"reference": "Jes 40,31"
|
||||
},
|
||||
"en": {
|
||||
"text": "But they that hope in the Lord shall renew their strength, they shall take wings as eagles, they shall run and not be weary, they shall walk and not faint.",
|
||||
"reference": "Is 40:31"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,9 @@ export function getErrorTitle(status: number, isEnglish: boolean): string {
|
||||
case 403: return 'Access Denied';
|
||||
case 404: return 'Page Not Found';
|
||||
case 500: return 'Server Error';
|
||||
case 502: return 'Bad Gateway';
|
||||
case 503: return 'Service Temporarily Unavailable';
|
||||
case 504: return 'Gateway Timeout';
|
||||
default: return 'Error';
|
||||
}
|
||||
}
|
||||
@@ -13,6 +16,9 @@ export function getErrorTitle(status: number, isEnglish: boolean): string {
|
||||
case 403: return 'Zugriff verweigert';
|
||||
case 404: return 'Seite nicht gefunden';
|
||||
case 500: return 'Serverfehler';
|
||||
case 502: return 'Bad Gateway';
|
||||
case 503: return 'Server vorübergehend nicht erreichbar';
|
||||
case 504: return 'Gateway-Zeitüberschreitung';
|
||||
default: return 'Fehler';
|
||||
}
|
||||
}
|
||||
@@ -24,6 +30,9 @@ export function getErrorDescription(status: number, isEnglish: boolean): string
|
||||
case 403: return 'You do not have permission for this area.';
|
||||
case 404: return 'The requested page could not be found.';
|
||||
case 500: return 'An unexpected error occurred. Please try again later.';
|
||||
case 502: return 'The site is briefly offline. Please try again in a few minutes.';
|
||||
case 503: return 'The site is briefly offline. Please try again in a few minutes.';
|
||||
case 504: return 'The upstream is taking too long to respond. Please try again shortly.';
|
||||
default: return 'An unexpected error occurred.';
|
||||
}
|
||||
}
|
||||
@@ -32,10 +41,30 @@ export function getErrorDescription(status: number, isEnglish: boolean): string
|
||||
case 403: return 'Du hast keine Berechtigung für diesen Bereich.';
|
||||
case 404: return 'Die angeforderte Seite konnte nicht gefunden werden.';
|
||||
case 500: return 'Es ist ein unerwarteter Fehler aufgetreten. Bitte versuche es später erneut.';
|
||||
case 502: return 'Die Seite ist gerade kurz offline. Bitte in ein paar Minuten erneut probieren.';
|
||||
case 503: return 'Die Seite ist gerade kurz offline. Bitte in ein paar Minuten erneut probieren.';
|
||||
case 504: return 'Der Server braucht zu lange zum Antworten. Bitte gleich nochmal probieren.';
|
||||
default: return 'Es ist ein unerwarteter Fehler aufgetreten.';
|
||||
}
|
||||
}
|
||||
|
||||
export interface BibleQuote {
|
||||
text: string;
|
||||
reference: string;
|
||||
}
|
||||
|
||||
// Generated at prebuild time by scripts/generate-error-quotes.ts from the
|
||||
// allioli (DE) + drb (EN) TSV bibles. Curated reference list lives in that
|
||||
// script; this JSON is the resolved verse text + display reference.
|
||||
import errorQuotesData from '$lib/data/errorQuotes.json';
|
||||
const errorQuotes = errorQuotesData as Record<string, { de: BibleQuote; en: BibleQuote }>;
|
||||
|
||||
export function getErrorBibleQuote(status: number, isEnglish: boolean): BibleQuote | null {
|
||||
const entry = errorQuotes[String(status)];
|
||||
if (!entry) return null;
|
||||
return isEnglish ? entry.en : entry.de;
|
||||
}
|
||||
|
||||
export const errorLabels = {
|
||||
login: { en: 'Log in', de: 'Anmelden' },
|
||||
tryAgain: { en: 'Try again', de: 'Erneut versuchen' },
|
||||
|
||||
Reference in New Issue
Block a user