Server Side Rendering
Setup Server Side Rendering (SSR) Page
Fastro provides built-in Server-Side Rendering (SSR) capabilities that allow you to render React components on the server and hydrate them on the client.
Overview
To create SSR pages, you need three main components:
- Component - The React component to render
- Layout - The HTML wrapper that includes head tags and structure
- Handler - The server-side logic that provides data to the component
Fastro automatically handles the build process, bundling, and hydration for you.
Basic Example
Create a Component
Create your React component in modules/web/hello.tsx
:
export default function Hello() {
return <h1>Hello, World!</h1>;
}
Create a Layout
Create the HTML layout in modules/web/app.layout.tsx
:
import { LayoutProps } from "https://fastro.deno.dev/http/server/types.ts";
export function layout({ data, children }: LayoutProps<{ title: string }>) {
return (
<html>
<head>
<title>{data.title}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div id="root">{children}</div>
</body>
</html>
);
}
Setup the Route
Create your main server file main.ts
:
import fastro from "https://fastro.deno.dev/mod.ts";
import { layout } from "./modules/web/app.layout.tsx";
import Hello from "./modules/web/hello.tsx";
const f = new fastro();
f.page("/", {
component: Hello,
layout,
handler: (_req, ctx) => ctx.render({ title: "Hello World" }),
folder: "modules/web",
});
await f.serve({ port: 8000 });
Interactive Example
Here's a more complete example with client-side interactivity:
Interactive Component
// modules/web/counter.tsx
import { useState } from "react";
export default function Counter(
{ initialCount = 0 }: { initialCount?: number },
) {
const [count, setCount] = useState(initialCount);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => setCount(count - 1)}>
Decrement
</button>
</div>
);
}
Route with Data
// main.ts
f.page("/counter", {
component: Counter,
layout,
handler: (_req, ctx) => {
const initialCount = Math.floor(Math.random() * 10);
return ctx.render({
title: "Counter App",
props: { initialCount },
});
},
folder: "modules/web",
});
Benefits
- SEO Friendly: Content is rendered server-side for better search engine indexing
- Fast Initial Load: Users see content immediately without waiting for JavaScript
- Progressive Enhancement: Pages work without JavaScript and enhance with it
- Automatic Hydration: Client-side interactivity is automatically enabled
Template
You can find a complete SSR example in the template repository.