diff --git a/composer.json b/composer.json
index c9268de..e782e43 100755
--- a/composer.json
+++ b/composer.json
@@ -11,7 +11,7 @@
"xp-forge/marshalling": "^2.4",
"xp-forge/web": "^4.6",
"xp-forge/web-auth": "^7.0",
- "xp-forge/frontend": "^7.0",
+ "xp-forge/frontend": "^7.4",
"xp-forge/rest-api": "^5.0",
"xp-forge/rest-client": "^6.0",
"xp-forge/handlebars-templates": "^4.0",
diff --git a/src/it/php/de/thekid/dialog/unittest/ServeTest.php b/src/it/php/de/thekid/dialog/unittest/ServeTest.php
index 38b2c7f..b20ae47 100755
--- a/src/it/php/de/thekid/dialog/unittest/ServeTest.php
+++ b/src/it/php/de/thekid/dialog/unittest/ServeTest.php
@@ -86,6 +86,15 @@ public function type_ahead_api_publicly_accessible() {
);
}
+ #[Test]
+ public function handles_404() {
+ $res= $this->serve('GET', '/not-found');
+ Assert::equals(
+ [404, 'text/html; charset=utf-8'],
+ [$res->status(), $res->headers()['Content-Type']]
+ );
+ }
+
#[Test]
public function upload_api_needs_authentication() {
$res= $this->serve('PUT', '/api/entries/test', ['Content-Type' => 'application/json; charset=utf-8'], '{
diff --git a/src/main/handlebars/errors/404.handlebars b/src/main/handlebars/errors/404.handlebars
new file mode 100755
index 0000000..40d3ad0
--- /dev/null
+++ b/src/main/handlebars/errors/404.handlebars
@@ -0,0 +1,25 @@
+{{#> layout}}
+ {{#*inline "title"}}Nicht gefunden{{/inline}}
+ {{#*inline "meta"}}
+
+
+
+
+ {{/inline}}
+ {{#*inline "main"}}
+
+
+
+
404: Seite nicht gefunden
+
+
+
+
+ Unter {{cause.path}} gibt es nichts zu sehen 🐸
+
+
+
+ » Zurück zur Startseite
+ {{/inline}}
+ {{#*inline "scripts"}}{{/inline}}
+{{/layout}}
\ No newline at end of file
diff --git a/src/main/handlebars/layout.handlebars b/src/main/handlebars/layout.handlebars
index aae5435..3dccc42 100755
--- a/src/main/handlebars/layout.handlebars
+++ b/src/main/handlebars/layout.handlebars
@@ -113,6 +113,34 @@
border-bottom-right-radius: .25rem;
}
+ .error {
+ margin-bottom: 2rem;
+
+ h1 {
+ font-size: 1.7rem;
+ color: currentColor;
+ }
+
+ svg {
+ display: block;
+ width: 16em;
+ margin: 3rem auto;
+ fill: currentColor;
+ }
+
+ p {
+ font-size: 1.15rem;
+ }
+
+ kbd {
+ padding: .25rem .25rem;
+ border-radius: .25rem;
+ background-color: var(--nav-color);
+ color: var(--text-color);
+ word-break: break-all;
+ }
+ }
+
.cover {
margin: -1rem -1rem 1rem -1rem;
background-size: cover;
@@ -919,7 +947,7 @@