This package contains the AWS Amplify React Router Adapter.
npm add aws-amplify amplify-adapter-react-router
You will need to create a runWithAmplifyServerContext
function to use Amplify APIs on the server-side of your React Router app.
You can create an amplifyServerUtils.ts
file under a lib
folder in your codebase. In this file, you will import the Amplify backend outputs from the amplify_outputs.json
file that is generated by the Amplify, and use the createServerRunner
function to create the runWithAmplifyServerContext
function.
For example, the lib/amplifyServerUtils.ts
file may contain the following content:
import { createServerRunner } from "amplify-adapter-react-router";
import outputs from "@/amplify_outputs.json";
export const { runWithAmplifyServerContext } = createServerRunner({
config: outputs,
});
To generate a data client for the React Router server runtime using request
and responseHeaders
, you only need to provide your Amplify configuration. When making the individual API requests, you will need to pass the config to the runWithAmplifyServerContext
function to pass in the cookies from request
and responseHeaders
variables.
You can create an amplify-ssr-client.ts
file under a lib
folder in your codebase. In this file, you will import the Amplify backend outputs from the amplify_outputs.json
file that is generated by the Amplify, and use the generateClient
function imported from aws-amplify/api/server
module to create the data client.
For example, the lib/amplify-ssr-client.ts
file may contain the following content:
import type { Schema } from "amplify/data/resource";
import { parseAmplifyConfig } from "aws-amplify/utils";
import { generateClient } from "aws-amplify/api/server";
import config from "../../amplify_outputs.json";
const amplifyConfig = parseAmplifyConfig(config);
export const client = generateClient<Schema>({
config: amplifyConfig,
});
When you use the Amplify library on the client-side of your React Router app, you will need to configure Amplify by calling the Amplify.configure
as you would to use Amplify in a single-page application.
Note: To use the Amplify library on the client side in a React Router app, you will need to set ssr to true when calling Amplify.configure
. This instructs the Amplify library to store tokens in the cookie store of a browser. Cookies will be sent along with requests to your React Router server for authentication.
import outputs from "@/amplify_outputs.json";
import { Amplify } from "aws-amplify";
Amplify.configure(outputs, {
ssr: true, // required when using Amplify with React Router Framework SSR
});
For the GraphQL API categories to use Amplify APIs on the server in your React Router app, you will need to:
- Use the
runWithAmplifyServerContext
helper function created by calling thecreateServerRunner
function exported fromamplify-adapter-react-router
to call the Amplify API in an isolated server context.
Now, you can use the runWithAmplifyServerContext
function to call Amplify APIs in an isolated server context. Create a new route app/routes/index.tsx
and use runWithAmplifyServerContext
in the loader function to call methods of the Amplify Data client, with the following code:
import type { Route } from "./+types/index";
import { TodoList } from "~/components/TodoList";
import { runWithAmplifyServerContext } from "~/lib/amplifyServerUtils";
import { data, Link } from "react-router";
import { client } from "~/lib/amplify-ssr-client";
export function meta() {
return [
{ title: "React Router Todo App" },
{ name: "description", content: "Todo List" },
];
}
export async function loader({ request }: Route.LoaderArgs) {
const responseHeaders = new Headers();
const { data: todos, errors } = await runWithAmplifyServerContext({
serverContext: { request, responseHeaders },
operation: (contextSpec) => client.models.Todo.list(contextSpec),
});
return data(
{
todos,
error: errors?.map((e) => e.message).join(", "),
},
{
headers: responseHeaders,
}
);
}
export default function Home({ loaderData }: Route.ComponentProps) {
const { todos } = loaderData;
return (
<div className="flex flex-col gap-y-3 my-4 mx-2">
<h1 className="text-2xl font-bold">Todo List</h1>
<TodoList items={todos} />
<Link to="/new">
<button
type="button"
className="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded"
>
Add Todo
</button>
</Link>
</div>
);
}