Implementing File-System Routing in Waku for Server-Side Rendering
Learn how to implement file-system routing in Waku to achieve server-side rendering, improve SEO, and avoid common hydration mismatches and security leaks.
30 Jun 2026, 07:55 UTC

Solving Initial Load Latency with Waku SSR
The primary challenge with client-side React applications is the "blank screen" effect, where users and search engine crawlers see an empty HTML shell until the JavaScript bundle downloads and executes. Waku solves this by using server-side rendering (SSR) and file-system routing to deliver fully formed HTML to the browser immediately.
The key takeaway is that Waku maps your directory structure directly to your URL paths. By placing a React component in the routes/ directory, Waku automatically handles the server-side render and the client-side hydration (the process of attaching event listeners to existing HTML), ensuring the page is visible before the JavaScript is fully active.
Setting Up a Route and Data Fetcher
In Waku, any file exported as a default component within the routes folder becomes a reachable page. To implement a page that requires server-side data, you can export a data-fetching function alongside your component. This ensures the data is available during the initial HTML generation on the server.
Example: Creating a Profile Page
// routes/profile.tsx
import { Link } from 'waku';
// This function runs only on the server
export async function getServerData() {
const response = await fetch('https://api.example.com/user');
const data = await response.json();
return { user: data };
}
export default function ProfilePage({ data }) {
return (
<div>
<h1>User Profile</h1>
<p>Welcome, {data.user.name}</p>
<Link href="/">Back to Home</Link>
</div>
);
}
Running and Verifying the Route
To deploy this route, use the Waku CLI from your terminal. Ensure you have the necessary permissions to execute binaries in your project directory.
- Development: Run
npm run dev(which callswaku dev). Navigate to/profilein your browser. - Verification: Right-click the page and select "View Page Source". You should see the
<p>Welcome, [Name]</p>text directly in the HTML, proving it was rendered on the server and not injected later by JavaScript. - Production: Run
npm run build(which callswaku build). Check the output directory to ensure the static assets and server bundles were generated.
Critical Engineering Constraints
While file-system routing simplifies navigation, SSR introduces specific risks that can lead to runtime errors or security vulnerabilities.
Hydration Mismatches
A hydration mismatch occurs when the HTML generated by the server differs from the first render on the client. This often happens when using browser-only globals like window or localStorage directly in the component body.
Incorrect: <div>{window.innerWidth}</div> (The server has no window object, so it renders nothing; the client renders a number. React will trigger a warning and may discard the server HTML).
Correct: Use a useEffect hook to update the state after the component has mounted on the client.
Server-Only Code Leakage
Waku attempts to separate server and client code, but developers must be cautious. Do not perform file-system reads (e.g., fs.readFileSync) or use private API keys inside the default exported component. Because this component is used for hydration, Waku may bundle that code for the browser, potentially exposing secrets or causing the build to fail when the browser encounters Node.js-specific modules.
Dynamic Route Parameters
When using dynamic segments (e.g., routes/user/[id].tsx), you must use Waku's specific route parameter API to access the ID. Attempting to read the URL directly from the window.location object during the initial render will return undefined on the server, causing the server-rendered HTML to be empty or incorrect.
Summary of Workflow
| Action | Command/Location | Expected Result |
|---|---|---|
| Add Page | routes/filename.tsx |
URL path /filename is created |
| Fetch Data | getServerData() |
Data available in component props on server |
| Verify SSR | View Page Source | Content visible without JavaScript |
| Production Build | waku build |
Optimized bundles in output folder |
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.