diff --git a/wmr/.gitignore b/wmr/.gitignore
new file mode 100644
index 0000000..bff902b
--- /dev/null
+++ b/wmr/.gitignore
@@ -0,0 +1,4 @@
+.cache
+node_modules
+dist
+stats.html
diff --git a/wmr/package.json b/wmr/package.json
new file mode 100644
index 0000000..4cb9364
--- /dev/null
+++ b/wmr/package.json
@@ -0,0 +1,21 @@
+{
+ "scripts": {
+ "start": "wmr",
+ "build": "wmr build --prerender",
+ "serve": "wmr serve"
+ },
+ "eslintConfig": {
+ "extends": "preact"
+ },
+ "alias": {
+ "react": "preact/compat",
+ "react-dom": "preact/compat"
+ },
+ "dependencies": {
+ "preact": "^10.5.12",
+ "preact-iso": "^1.0.0"
+ },
+ "devDependencies": {
+ "wmr": "^1.2.0"
+ }
+}
diff --git a/wmr/public/header.js b/wmr/public/header.js
new file mode 100644
index 0000000..d4ead22
--- /dev/null
+++ b/wmr/public/header.js
@@ -0,0 +1,22 @@
+import { useLocation } from "preact-iso/router";
+
+export default function Header() {
+ const { url } = useLocation();
+ return (
+
+ );
+}
diff --git a/wmr/public/index.html b/wmr/public/index.html
new file mode 100644
index 0000000..d7d61dc
--- /dev/null
+++ b/wmr/public/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+ WMR App
+
+
+
+
+
+
+
+
+
+
diff --git a/wmr/public/index.js b/wmr/public/index.js
new file mode 100644
index 0000000..d4bbf91
--- /dev/null
+++ b/wmr/public/index.js
@@ -0,0 +1,32 @@
+import hydrate from "preact-iso/hydrate";
+import { LocationProvider, Router } from "preact-iso/router";
+import lazy, { ErrorBoundary } from "preact-iso/lazy";
+import Home from "./pages/home/index.js";
+import NotFound from "./pages/_404.js";
+import Header from "./header.js";
+
+const About = lazy(() => import("./pages/about/index.js"));
+
+export function App() {
+ return (
+
+
+
+ );
+}
+
+hydrate();
+
+export async function prerender(data) {
+ const { default: prerender } = await import("preact-iso/prerender");
+ return await prerender();
+}
diff --git a/wmr/public/pages/_404.js b/wmr/public/pages/_404.js
new file mode 100644
index 0000000..0e1b50c
--- /dev/null
+++ b/wmr/public/pages/_404.js
@@ -0,0 +1,8 @@
+const NotFound = () => (
+
+ 404: Not Found
+ It's gone :(
+
+);
+
+export default NotFound;
diff --git a/wmr/public/pages/about/index.js b/wmr/public/pages/about/index.js
new file mode 100644
index 0000000..c583e22
--- /dev/null
+++ b/wmr/public/pages/about/index.js
@@ -0,0 +1,11 @@
+import styles from "./style.module.css";
+
+const About = ({ query }) => (
+
+ About
+ A page all about this website.
+ {JSON.stringify(query)}
+
+);
+
+export default About;
diff --git a/wmr/public/pages/about/style.module.css b/wmr/public/pages/about/style.module.css
new file mode 100644
index 0000000..1eab45c
--- /dev/null
+++ b/wmr/public/pages/about/style.module.css
@@ -0,0 +1,3 @@
+.about {
+ background: #dbcfe7;
+}
diff --git a/wmr/public/pages/home/index.js b/wmr/public/pages/home/index.js
new file mode 100644
index 0000000..9f4463c
--- /dev/null
+++ b/wmr/public/pages/home/index.js
@@ -0,0 +1,24 @@
+import styles from "./style.module.css";
+import { useState } from "preact/hooks";
+
+export default function Home() {
+ const [count, setCount] = useState(0);
+
+ return (
+ <>
+
+ Home
+ This is the home page.
+ <>
+
+
+
+ >
+
+ >
+ );
+}
diff --git a/wmr/public/pages/home/style.module.css b/wmr/public/pages/home/style.module.css
new file mode 100644
index 0000000..84ba682
--- /dev/null
+++ b/wmr/public/pages/home/style.module.css
@@ -0,0 +1,4 @@
+.home {
+ background: #f6f6f6;
+ color: #333;
+}
diff --git a/wmr/public/style.css b/wmr/public/style.css
new file mode 100644
index 0000000..ba18c52
--- /dev/null
+++ b/wmr/public/style.css
@@ -0,0 +1,45 @@
+html,
+body {
+ margin: 0;
+ min-height: 100%;
+ font-family: system-ui, sans-serif;
+}
+
+header {
+ display: flex;
+ background: #ddd;
+}
+
+header > nav {
+ flex: 1;
+ display: flex;
+}
+
+header > nav a {
+ padding: 10px;
+ color: #673ab8;
+ text-decoration: none;
+}
+
+header > nav a:hover {
+ background-color: #f1e9ff;
+}
+
+header > label {
+ display: flex;
+ align-items: center;
+ padding: 10px;
+ color: #555;
+ font-size: 80%;
+}
+
+header input {
+ border: none;
+ border-radius: 3px;
+ padding: 2px 5px;
+ font-size: 100%;
+}
+
+.app > section {
+ padding: 20px;
+}
diff --git a/wmr/tsconfig.json b/wmr/tsconfig.json
new file mode 100644
index 0000000..6449765
--- /dev/null
+++ b/wmr/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "compilerOptions": {
+ "jsx": "preserve",
+ "jsxFactory": "preact.h",
+ "jsxFragmentFactory": "preact.Fragment",
+ "allowJs": true,
+ "checkJs": true,
+ "strict": true,
+ "noEmit": true,
+ "moduleResolution": "node",
+ "target": "esnext",
+ "module": "esnext",
+ "resolveJsonModule": true,
+ "allowSyntheticDefaultImports": true,
+ "downlevelIteration": true
+ }
+}
diff --git a/wmr/yarn.lock b/wmr/yarn.lock
new file mode 100644
index 0000000..a9075e7
--- /dev/null
+++ b/wmr/yarn.lock
@@ -0,0 +1,23 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+fsevents@^2.1.3:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+ integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+
+preact-iso@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/preact-iso/-/preact-iso-1.1.1.tgz#959656bfee479e6a8c6707753e84d4342f61c48b"
+ integrity sha512-/iG9YH2nlLf3DAEXxCxka6Mux32t2cZEgfbvkNnR9ZtK0yjDRBEHI1IJS6I1AtelAFuBvoD24Ua0sc7wdZb1vg==
+
+preact@^10.5.12:
+ version "10.5.13"
+ resolved "https://registry.yarnpkg.com/preact/-/preact-10.5.13.tgz#85f6c9197ecd736ce8e3bec044d08fd1330fa019"
+ integrity sha512-q/vlKIGNwzTLu+jCcvywgGrt+H/1P/oIRSD6mV4ln3hmlC+Aa34C7yfPI4+5bzW8pONyVXYS7SvXosy2dKKtWQ==
+
+wmr@^1.2.0:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/wmr/-/wmr-1.5.1.tgz#f7630da86ff69eef935c7b8361230482d06bc880"
+ integrity sha512-CW+cMxaTFsCgBmcQXeuvTJ0rM5+IhOOA0f8xAZdfre63TNlEoOw0T3G8bKYRV7N+SaveF3siRFis96rSVnyMuQ==