Skip to content

Commit

Permalink
wip: multi pages
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa committed Dec 19, 2024
1 parent d3c7459 commit e8c8a97
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 35 deletions.
Binary file added react-server-dom-vite-example/public/favicon.ico
Binary file not shown.
50 changes: 19 additions & 31 deletions react-server-dom-vite-example/src/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,27 @@
import { changeCounter, getCounter } from "./action";
import { Counter, Hydrated } from "./client";

export async function App() {
export async function IndexPage() {
return (
<html>
<head>
<meta charSet="UTF-8" />
<title>react-server</title>
<meta
name="viewport"
content="width=device-width, height=device-height, initial-scale=1.0"
/>
</head>
<body>
<div>
<div>server random: {Math.random().toString(36).slice(2)}</div>
<Hydrated />
<Counter />
<form
action={changeCounter}
data-testid="server-counter"
style={{ padding: "0.5rem" }}
>
<div>Server counter: {getCounter()}</div>
<div>
<div>server random: {Math.random().toString(36).slice(2)}</div>
<Hydrated />
<Counter />
<form
action={changeCounter}
data-testid="server-counter"
style={{ padding: "0.5rem" }}
>
<div>Server counter: {getCounter()}</div>
<div>
<button name="change" value="-1">
-
</button>
<button name="change" value="+1">
+
</button>
</div>
</form>
<button name="change" value="-1">
-
</button>
<button name="change" value="+1">
+
</button>
</div>
</body>
</html>
</form>
</div>
);
}
25 changes: 25 additions & 0 deletions react-server-dom-vite-example/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export function Layout(props: React.PropsWithChildren) {
return (
<html>
<head>
<meta charSet="UTF-8" />
<title>react-server</title>
<meta
name="viewport"
content="width=device-width, height=device-height, initial-scale=1.0"
/>
</head>
<body>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/other">Other</a>
</li>
</ul>
{props.children}
</body>
</html>
);
}
3 changes: 3 additions & 0 deletions react-server-dom-vite-example/src/app/other.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function OtherPage() {
return <div>Other Page</div>;
}
14 changes: 14 additions & 0 deletions react-server-dom-vite-example/src/app/routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type React from "react";
import { IndexPage } from ".";
import { Layout } from "./layout";
import OtherPage from "./other";

const routes: Record<string, React.ReactNode> = {
"/": <IndexPage />,
"/other": <OtherPage />,
};

export function Router(props: { url: URL }) {
const page = routes[props.url.pathname] ?? <h4>Not found</h4>;
return <Layout>{page}</Layout>;
}
27 changes: 25 additions & 2 deletions react-server-dom-vite-example/src/entry.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async function main() {
}, [startTransition, setPayload_]);

React.useEffect(() => {
return listenWindowHistory(onNavigation);
return listenNavigation(onNavigation);
}, []);

return payload.root;
Expand All @@ -69,7 +69,7 @@ async function main() {
}
}

function listenWindowHistory(onNavigation: () => void) {
function listenNavigation(onNavigation: () => void) {
window.addEventListener("popstate", onNavigation);

const oldPushState = window.history.pushState;
Expand All @@ -86,7 +86,30 @@ function listenWindowHistory(onNavigation: () => void) {
return res;
};

function onClick(e: MouseEvent) {
let link = (e.target as Element).closest("a");
if (
link &&
link instanceof HTMLAnchorElement &&
link.href &&
(!link.target || link.target === "_self") &&
link.origin === location.origin &&
!link.hasAttribute("download") &&
e.button === 0 && // left clicks only
!e.metaKey && // open in new tab (mac)
!e.ctrlKey && // open in new tab (windows)
!e.altKey && // download
!e.shiftKey &&
!e.defaultPrevented
) {
e.preventDefault();
history.pushState(null, "", link.href);
}
}
document.addEventListener("click", onClick);

return () => {
document.removeEventListener("click", onClick);
window.removeEventListener("popstate", onNavigation);
window.history.pushState = oldPushState;
window.history.replaceState = oldReplaceState;
Expand Down
4 changes: 2 additions & 2 deletions react-server-dom-vite-example/src/entry.rsc.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ReactServer from "@jacob-ebey/react-server-dom-vite/server";
import type { ReactFormState } from "react-dom/client";
import { App } from "./app";
import { Router } from "./app/routes";
import type {
ClientReferenceMetadataManifest,
ServerReferenceManifest,
Expand Down Expand Up @@ -57,7 +57,7 @@ export async function handler(
const stream = fromPipeableToWebReadable(
ReactServer.renderToPipeableStream<ServerPayload>(
{
root: <App />,
root: <Router url={url} />,
returnValue,
formState,
},
Expand Down

0 comments on commit e8c8a97

Please sign in to comment.