React Router SSR, with no Node server to keep running
React Router SSR from one Function: a list page with a loader, a detail page, and a form with an action. The client build goes up in the same deploy, and nothing runs between visits.
There's no server to keep running
You want React rendered on the server, but you don't want a Node process up all day, waiting for visitors. Here, each visit starts your code, renders the page, and stops. Between visits nothing runs.
The whole template is public. Read it before you trust it.
Or scaffold it
$ npx wawesome init --template react-ssr
$ npx wawesome deployWhat you get
A React Router v7 app in framework mode, deployed as
one Function called root. The server and the client build deploy together and
roll back together. If you know the React Router docs, you know where
everything is:
app/root.tsx the document and the error page
app/routes/home.tsx the list: a loader, and a form with an action
app/routes/book.tsx one book: a loader that answers 404 for an unknown id
app/books.ts the data, as a fixed list
server.ts the Function: React Router's request handler as `fetch`
The list page reads its data in a loader, so the books are in the HTML before
any script runs:
export async function loader({ request }: Route.LoaderArgs) {
const suggested = new URL(request.url).searchParams.get("suggested");
return { books: await listBooks(), suggested };
}
The form posts to an action in the same file. A blank title gets a 400.
Otherwise the action redirects, so a reload doesn’t post again.
Run it
npx wawesome init --template react-ssr
It offers to log you in if you aren’t. Then it asks for a Function name and an
App slug. Keep the name root, the only one that answers at your App’s own
hostname. If you haven’t deployed yet, it offers to change your workspace
address, which locks at your first deploy. There’s nothing else to set. It
deploys and prints the address. Open it and view the page source. The list is
already in the HTML.
To work on it locally, run npm run dev, React Router’s own dev server.
What to change first
The data in app/books.ts. It’s a fixed list, and the form doesn’t save
anything. To keep what people send, have the action write it to a database you
reach over fetch, such as a Supabase table. Add that host to your App’s
allowlist first, because outbound calls are closed by default.
What it doesn’t do
It doesn’t answer under a preview URL. The engine has no Intl, and
toLocaleString ignores the locale, so a price that shows 1,234.50 on your
machine shows 1234.5 in production. npm test fails on each use, so run it
before you deploy. One render has a fixed fuel budget, so paginate long lists.
When a render throws, the page shows the error boundary in app/root.tsx, and
we put the stack in your logs: npx wawesome logs --follow.
- react
- react-router
- ssr
- vite
- frontend
- typescript
Ready in about a minute
Sign in with GitHub, deploy, and get a public HTTPS endpoint.