Quick Start
This guide walks you through building your first Cloudwerk application with pages, data loading, and API routes.
Create Your First Page
Section titled “Create Your First Page”-
Create a new page file at
app/page.tsx:// app/page.tsxexport default function HomePage() {return (<div><h1>Welcome to Cloudwerk</h1><p>Your full-stack framework for Cloudflare Workers.</p></div>);} -
Start the dev server:
Terminal window pnpm dev -
Open http://localhost:8787 to see your page.
Add Data Loading
Section titled “Add Data Loading”Cloudwerk uses loader() functions for server-side data fetching:
// app/page.tsximport type { PageProps, LoaderArgs } from '@cloudwerk/core';
export async function loader({ context }: LoaderArgs) { // Access D1 database via Cloudflare bindings const db = context.env.DB; const { results: posts } = await db .prepare('SELECT id, title, excerpt FROM posts ORDER BY created_at DESC LIMIT 10') .all();
return { posts };}
interface Props extends PageProps { posts: Array<{ id: string; title: string; excerpt: string }>;}
export default function HomePage({ posts }: Props) { return ( <div> <h1>Latest Posts</h1> <ul> {posts.map((post) => ( <li key={post.id}> <a href={`/posts/${post.id}`}>{post.title}</a> <p>{post.excerpt}</p> </li> ))} </ul> </div> );}Create Dynamic Routes
Section titled “Create Dynamic Routes”Use brackets [param] for dynamic route segments:
// app/posts/[id]/page.tsximport type { PageProps, LoaderArgs } from '@cloudwerk/core';import { NotFoundError } from '@cloudwerk/core';
export async function loader({ params, context }: LoaderArgs) { const db = context.env.DB; const post = await db .prepare('SELECT id, title, content FROM posts WHERE id = ?') .bind(params.id) .first();
if (!post) { throw new NotFoundError('Post not found'); }
return { post };}
interface Props extends PageProps { post: { id: string; title: string; content: string };}
export default function PostPage({ post }: Props) { return ( <article> <h1>{post.title}</h1> <div>{post.content}</div> </article> );}Add a Layout
Section titled “Add a Layout”Layouts wrap pages and persist across navigation:
// app/layout.tsximport type { LayoutProps } from '@cloudwerk/core';
export default function RootLayout({ children }: LayoutProps) { return ( <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>My Cloudwerk App</title> </head> <body> <nav> <a href="/">Home</a> <a href="/about">About</a> </nav> <main>{children}</main> <footer> <p>Built with Cloudwerk</p> </footer> </body> </html> );}Create an API Route
Section titled “Create an API Route”API routes handle HTTP requests without rendering UI:
// app/api/posts/route.tsimport type { CloudwerkHandlerContext } from '@cloudwerk/core';import { json, getContext } from '@cloudwerk/core';
export async function GET(request: Request, { params }: CloudwerkHandlerContext) { const { env } = getContext(); const { results: posts } = await env.DB .prepare('SELECT * FROM posts ORDER BY created_at DESC') .all();
return json(posts);}
export async function POST(request: Request, { params }: CloudwerkHandlerContext) { const { env } = getContext(); const body = await request.json(); const id = crypto.randomUUID();
await env.DB .prepare('INSERT INTO posts (id, title, content, created_at) VALUES (?, ?, ?, ?)') .bind(id, body.title, body.content, new Date().toISOString()) .run();
return json({ id, title: body.title }, { status: 201 });}Add Middleware
Section titled “Add Middleware”Middleware runs before route handlers:
// app/middleware.tsimport type { Middleware } from '@cloudwerk/core';
export const middleware: Middleware = async (request, next) => { const start = Date.now();
// Run the route handler const response = await next();
// Add timing header const duration = Date.now() - start; response.headers.set('X-Response-Time', `${duration}ms`);
return response;};Deploy to Cloudflare
Section titled “Deploy to Cloudflare”Deploy your application globally:
pnpm deployYour app is now live on Cloudflare Workers!
Next Steps
Section titled “Next Steps”- Project Structure - Understand file conventions
- Routing Guide - Learn advanced routing patterns
- Data Loading - Master server-side data fetching
- Database Guide - Connect to Cloudflare D1