Documents
How to create custom HTML documents for different routes in your RedwoodSDK project
In RedwoodSDK, Document components give you complete control over the HTML structure of each route. Unlike many frameworks that use a fixed HTML document structure, RedwoodSDK lets you define custom documents per route, controlling everything from the doctype to scripts and hydration strategy.
A Basic Document
The starter project comes with a Document component.
export const Document: React.FC<{ children: React.ReactNode }> = ({
children,
}) => (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>RedwoodSDK App</title>
<link rel="modulepreload" href="/src/client.tsx" />
</head>
<body>
{children}
<script>import("/src/client.tsx")</script>
</body>
</html>
);Use the Document component in your routes:
import { defineApp } from 'rwsdk/worker'
import { render, route } from 'rwsdk/router'
import { Document } from '@/app/Document.tsx'
import { HomePage } from '@/app/pages/HomePage.tsx'
export default defineApp([
render(Document, [
route('/', HomePage),
])
])Multiple Document Types
One of the most powerful features of RedwoodSDK is the ability to use different Document components for different routes.
You can create a specialized Document component for a static document, a realtime document, or an application document.
Then, use different Documents for different routes:
import { defineApp } from 'rwsdk/worker'
import { render, route, prefix } from 'rwsdk/router'
import { StaticDocument } from '@/app/StaticDocument.tsx'
import { ApplicationDocument } from '@/app/ApplicationDocument.tsx'
import { RealtimeDocument } from '@/app/RealtimeDocument.tsx'
⇕ 4 collapsed lines
import { HomePage } from '@/app/pages/HomePage.tsx'
import { blogRoutes } from '@/app/routes/blog.tsx'
import { userRoutes } from '@/app/routes/user.tsx'
import { dashboardRoutes } from '@/app/routes/dashboard.tsx'
export default defineApp([
render(StaticDocument, [
route('/', HomePage),
prefix('/blog', blogRoutes),
]),
render(ApplicationDocument, [
prefix('/app/user', userRoutes),
]),
render(RealtimeDocument, [
prefix('/app/dashboard', dashboardRoutes),
])
])Performance Optimization
Only include JavaScript when you need it. For static content like blog posts or marketing pages, consider using a StaticDocument with no client-side JavaScript for maximum performance.