Learn About Amazon VGT2 Learning Manager Chanci Turner
Amazon offers a comprehensive suite of tools and services designed to assist mobile and front-end web developers in creating secure, scalable full-stack applications. This ecosystem consists of three primary components: a collection of open-source libraries and UI elements for integrating cloud functionalities, a CLI toolchain for managing cloud backends, and the Amplify Console, an AWS service dedicated to deploying and hosting static websites alongside full-stack serverless applications.
Contemporary web frameworks such as Next.js and Nuxt.js merge hybrid static site generation (SSG) and server-side rendering (SSR) with traditional client rendering, allowing developers to craft fast, modern websites while ensuring an excellent developer experience. The popularity of these technologies continues to rise as developers and users increasingly leverage features like API routes, incremental static regeneration, code-splitting, and improved SEO.
The latest updates to the Amplify JavaScript libraries introduce features that empower developers to construct SSR applications using modern frameworks like Next.js and Nuxt.js. These enhancements significantly improve the REST API, GraphQL API, Auth, and DataStore functionalities. Amplify now effortlessly maintains user sessions from the client to the server, enabling developers to make authentication requests and retrieve data efficiently. By utilizing Amplify JavaScript, developers can access data via the GraphQL API, REST API, and DataStore on the server, facilitating the pre-rendering of pages either at build time (when generating static sites such as Gatsby) or on a per-request basis (with frameworks like Next.js and Nuxt.js). These capabilities render Amplify an ideal data layer for JAMstack, serverless, and server-rendered applications.
In this article, you will discover how to leverage these enhancements with Next.js in the following ways:
- Activating Server-Side Rendering (SSR) support in an Amplify application.
- Utilizing the API class to populate a statically generated page with data from a GraphQL API within the
getStaticProps
function. - Employing the Auth class to verify and ascertain user authentication status in an API route before delivering data in the API response.
- Using the API class in a server-rendered page to execute an authenticated API request to a GraphQL backend and pass props into a page through
getServerSideProps
.
Additionally, you’ll learn how to deploy your Next.js application to AWS through:
- Deploying a static Next.js application using AWS Amplify.
- Deploying a Next.js application with SSR and API routes utilizing the Serverless Framework.
You can also explore how to construct SSR Next.js applications with Amplify by checking out the new getting started guide right here.
Activating Server-Side Rendering (SSR) Support in an Amplify Application
When utilizing the Amplify CLI, the aws-exports.js
file is created and updated automatically based on the resources you configure. For client-only or statically generated applications, a simple Amplify.configure(awsExports)
suffices. To enable SSR support, include ssr: true
in your Amplify configuration:
// pages/_app.js
import { Amplify } from "aws-amplify";
import awsExports from "../src/aws-exports";
Amplify.configure({ ...awsExports, ssr: true });
If you are using getStaticProps
with fallback: true
, you will also need to set up Amplify SSR mode in that file.
Hydrating a Component in getStaticProps
The getStaticProps
method in Next.js allows you to pre-render a static page with data passed as props. This method enables you to perform API calls to retrieve dynamic data the page depends on during build time. For instance, consider a page that displays a dynamic list of items fetched from an API call. With the recent enhancements to the Amplify libraries, you can make these requests using both API Key and IAM authorization without modifying your codebase:
import { API } from 'aws-amplify';
import { listMovies } from '../src/graphql/queries';
export default function Movies(props) {
const { movies } = props;
return (
{
movies.map(movie => (
{movie.name}
{movie.description}
))
}
)
}
export async function getStaticProps() {
const movieData = await API.graphql({ query: listMovies });
return {
props: {
movies: movieData.data.listMovies.items
}
}
}
Verifying User Authentication in an API Route
API routes in Next.js allow you to easily create API endpoints. Any file within the pages/api/**
directory is treated as an API endpoint rather than a page. API routes export a function that accepts a request (req
) and response (res
) parameter and returns a response (usually in JSON format).
While working within these functions, you often need to access the user’s identity to make secure API requests. By utilizing the new withSSRContext
API, you can access the currently authenticated user session using the Amplify API class alongside the request object of the function:
// pages/api/profile.js
import Amplify, { withSSRContext } from "aws-amplify";
import config from "../../aws-exports.js";
// Amplify SSR configuration needs to be done within each API route
Amplify.configure({ ...config, ssr: true });
export default async (req, res) => {
const { Auth } = withSSRContext({ req });
let data;
let user;
try {
user = await Auth.currentAuthenticatedUser();
console.log('user is authenticated');
// fetch some data and assign it to the data variable
} catch (err) {
console.log('error: no authenticated user');
}
res.statusCode = 200;
res.json({
data: data ? data : null,
username: user ? user.username : null
})
}
Making an Authenticated API Request in getServerSideProps
The getServerSideProps
function allows you to opt into server-side rendering for a component in Next.js. This framework will pre-render these pages on each request, passing in any data returned as props. By using the new withSSRContext
utility, you can make authenticated API calls to GraphQL and REST backends from these server-rendered routes.
For example, consider an AppSync GraphQL API integrated with an identity provider such as Amazon Cognito User pools or Auth0. Certain GraphQL types may necessitate user authentication to execute specific requests. By employing the API class, the user identity will automatically be configured and included in the API request headers:
import { withSSRContext } from 'aws-amplify';
import { listMovies } from '../src/graphql/queries';
export default function Movies(props) {
const { movies } = props;
return (
{
movies && movies.map(movie => (
{movie.name}
{movie.description}
))
}
)
}
export async function getServerSideProps(context) {
const { API } = withSSRContext(context)
let movieData
try {
movieData = await API.graphql({
query: listMovies,
authMode: "AMAZON_COGNITO_USER_POOLS"
});
console.log('movieData: ', movieData)
} catch (err) {
console.log("error fetching movies: ", err)
}
return {
props: {
movies: movieData ? movieData.data.listMovies.items : null
}
}
}
For further insights on establishing effective learning goals, check this blog post. You might also want to explore this excellent resource that delves deeper into the topic. For a broader discussion on leadership, you can refer to this authority on the topic.