Skip to content

ReactRouter

Source: src/AWS/Website/ReactRouter.ts

Deploy a React Router v7 app (framework mode) to AWS: the SSR server on a streaming Lambda Function URL, client assets in S3, and a CloudFront distribution whose edge router serves uploaded files from S3 and forwards everything else to the server.

The build runs through @alchemy.run/frontend-frameworks/react-router with the @alchemy.run/frontend-frameworks/react-router/aws deploy target — both must be installed in your project, alongside @react-router/dev, react-router, and vite.

Your vite.config.ts needs no adapter wiring. React Router’s server build is a ServerBuild manifest rather than a request handler, so the integration makes the server pass’s build input a module that wraps the manifest with createRequestHandler, forces the SSR bundle to be self-contained, and packages the resulting fetch handler as a streaming Lambda handler.

React Server Components (React Router’s unstable RSC plugin) and multi-environment builds are not supported yet — the build fails with an actionable error when more than one server entry is emitted.

Basic React Router App

const site = yield* AWS.Website.ReactRouter("Web", {
rootDir: "./app",
});

Custom Domain

const site = yield* AWS.Website.ReactRouter("Web", {
rootDir: "./app",
domain: {
name: "app.example.com",
hostedZoneId: zone.hostedZoneId,
},
});

Tune The Server Function

const site = yield* AWS.Website.ReactRouter("Web", {
rootDir: "./app",
memorySize: 2048,
env: {
API_BASE: api.url,
},
});

Read An Environment Variable From A Loader

app/routes/home.tsx
export function loader() {
return { apiBase: process.env.API_BASE ?? "unset" };
}
const router = yield* AWS.Website.Router("FrontDoor", {});
const site = yield* AWS.Website.ReactRouter("Web", {
rootDir: "./app",
domain: { router },
});