Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated May 16, 2024

Next.js server runtime

This guide walks through how you can connect to Amplify Data from Next.js Server-side Runtimes (SSR). For Next.js applications, Amplify provides first-class support for the App Router (React Server Components, Route Handlers, and Server Actions), the Pages Router (Components, API Routes), and Middleware.

Before you begin, you will need:

Connect to Amplify Data from a Next.js server runtime

Connecting to Amplify Data will include choosing the correct data client for Next.js server runtimes, generating the data client, and then calling the API.

Step 1 - Choose the correct Data client for Next.js server runtimes

Amplify offers two specialized data clients for Next.js server runtimes (from @aws-amplify/adapter-nextjs/data) that you should use depending whether you retrieve the user tokens using cookies or NextRequest and NextResponse:

  • generateServerClientUsingCookies() 🍪 generates a data client with the Next.js cookies function from next/headers. Each API request dynamically refetches the cookies at runtime.
  • generateServerClientUsingReqRes() 🌐 generates a data client requiring NextRequest and NextResponse provided to an runWithAmplifyServerContext function to prevent token contamination.

Choose the correct data client based on your Next.js Router (App or Pages) and then the use case:

Use caseRequired Data client
React Server ComponentgenerateServerClientUsingCookies() 🍪
Server ActionsgenerateServerClientUsingCookies() 🍪
Route HandlergenerateServerClientUsingCookies() 🍪
MiddlewaregenerateServerClientUsingReqRes() 🌐

Pages Router

Use caseRequired Data client
Server-side component codegenerateServerClientUsingReqRes() 🌐
API RoutegenerateServerClientUsingReqRes() 🌐
MiddlewaregenerateServerClientUsingReqRes() 🌐

Step 2 - Generate the Data client for Next.js server runtimes

To generate a Data client for the Next.js server runtime using cookies, you need to provide both your Amplify configuration and the cookies function from Next.js.

import { type Schema } from '@/amplify/data/resource';
import { generateServerClientUsingCookies } from '@aws-amplify/adapter-nextjs/data';
import outputs from '@/amplify_outputs.json';
import { cookies } from 'next/headers';
export const cookieBasedClient = generateServerClientUsingCookies<Schema>({
config: outputs,
cookies,
});

We recommend you generate Amplify Data's server client in a utility file. Then, import the generated client in your Next.js React Server Components, Server Actions, or Route Handlers.

To generate a data client for the Next.js server runtime using NextRequest and NextResponse, 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 response variables.

import { type Schema } from '@/amplify/data/resource';
import { createServerRunner } from '@aws-amplify/adapter-nextjs';
import { generateServerClientUsingReqRes } from '@aws-amplify/adapter-nextjs/data';
import outputs from '@/amplify_outputs.json';
export const { runWithAmplifyServerContext } = createServerRunner({
config: outputs,
});
export const reqResBasedClient = generateServerClientUsingReqRes<Schema>({
config: outputs,
});

We recommend you generate the server Data client in a utility file. Then, import the generated client in your Next.js Middleware, component's server runtime code, and API Routes.

Step 3 - Call API using generated server Data clients

You can make any available query or mutation request with the generated server data clients; however, note that subscriptions are not available within server runtimes.

Import the cookie-based server Data client in your Next.js React Server Component code and make your API requests.

import { type Schema } from '@/amplify/data/resource';
import { generateServerClientUsingCookies } from '@aws-amplify/adapter-nextjs/data';
import outputs from '@/amplify_outputs.json';
import { cookies } from 'next/headers';
export const cookieBasedClient = generateServerClientUsingCookies<Schema>({
config: outputs,
cookies,
});
const fetchTodos = async () => {
const { data: todos, errors } = await cookieBasedClient.models.Todo.list();
if (!errors) {
return todos;
}
};

Import the NextRequest/NextResponse-based server Data client in your Next.js server runtime code and make your API requests within the runWithAmplifyServerContext function. Review Server-side Rendering to learn more about creating an Amplify server context.

For example, in a Next.js Pages Router API route, use the req and res parameters from the handler function with runWithAmplifyServerContext:

import { type Schema } from '@/amplify/data/resource';
import type { NextApiRequest, NextApiResponse } from 'next';
import {
runWithAmplifyServerContext,
reqResBasedClient,
} from '@/utils/amplifyServerUtils';
type ResponseData = {
todos: Schema['Todo']['type'][];
};
export default async function handler(
request: NextApiRequest,
response: NextApiResponse<ResponseData>
) {
const todos = await runWithAmplifyServerContext({
nextServerContext: { request, response },
operation: async (contextSpec) => {
const { data: todos } = await reqResBasedClient.models.Todo.list(
contextSpec
);
return todos;
},
});
response.status(200).json({ todos });
}