Done in 10 minutes. Easy deployment procedure for a Next.js app using the official AWS Amplify template

  • aws
    aws
  • nextjs
    nextjs
  • amplify
    amplify
Published on 2024/11/05

Introduction

The first deployment target that usually comes to mind for Next.js is probably Vercel.

It’s very convenient because it supports the latest Next.js features, but depending on the company, there are cases where platforms are consolidated on AWS or Azure, and Vercel cannot be used.

It has long been possible to deploy Next.js to AWS, but there are various services that can be candidates as deployment targets.

However, when it comes to actually deploying, you need a fair amount of AWS knowledge, which can be a bit of a hurdle for engineers who mainly work on the frontend.

This time, we’ll deploy Next.js using AWS Amplify, which allows deployment with relatively little AWS knowledge.

Official documentation

The official AWS Amplify documentation describes how to get started with the Next.js App Router.

We’ll proceed with the deployment work based on this document.

https://docs.amplify.aws/nextjs/start/quickstart/nextjs-app-router-client-components/

And this is the AWS Amplify Next.js (App Router) Starter Template we’ll use this time.

As of November 2024, it appears to be using Next.js Version 14.

https://github.com/aws-samples/amplify-next-template

There are several configuration files for deploying to Amplify, but we’ll explain them in detail when needed.

Goal for this article

We’ll use the Next.js template repository provided by AWS to deploy to AWS Amplify and confirm that we can actually access the app.

After that, we’ll modify the Next.js code in the local environment, redeploy to Amplify, and confirm that the changes are reflected.

We’ll be deploying an app that manages Todos like the one below.

Image from Gyazo

Prerequisites for using AWS Amplify

  • Your local environment must be set up so that you can use git and node.js for development
  • You must have an AWS account

Deployment steps

Let’s get started with the deployment.

First, copy the template app into your own repository.

Click “Create repository from template” in the official documentation to copy it.

Image from Gyazo

In the AWS Amplify screen, select GitHub.

Image from Gyazo

Select the repository you just created.

Image from Gyazo

You can configure the app settings.

For now, we’ll prioritize just getting it deployed, so we’ll leave everything as is.

Image from Gyazo

This is the final confirmation of the settings.

As noted on the screen, the initial deployment will take about 2–5 minutes.

Image from Gyazo

Once the deployment is complete, AWS will assign a URL that you can access.

Image from Gyazo

If you access the URL and see a screen like the one below, the deployment is complete.

The template app provided this time appears to be a Todo app.

Click +new, and when the dialog appears, enter text to save a Todo.

Image from Gyazo

I added a Todo called “Do homework.” (I also added one blank Todo, so there’s a mysterious empty row. I’ll delete it later.)

Image from Gyazo

That’s it for the simple deployment steps.

Depending on the deployment time, it may vary a bit, but you should have been able to complete everything in about 10 minutes, even while reading the explanation.

For those thinking “This alone isn’t very useful in a real development environment,” I’ll now introduce some more practical content.

Local development

Next, we’ll go over how to develop in your local environment.

This time, we’ll try adding a delete button as described in the official documentation.

Copy the repository to your local machine

First, clone the repository you copied earlier to your local environment.

Then download the required packages.

git clone git@github.com:shinagawa-web/amplify-next-template.git
cd amplify-next-template && npm install

Download backend configuration information

Go back to the Amplify console for a moment.

Open the Deployed backend resources tab, and you’ll see a button labeled Download amplify_outputs.json file. Click it to download the json file.

Image from Gyazo

Here’s a brief explanation of amplify_outputs.json.

{
  "auth": {
    "user_pool_id": "ap-northeast-1_GWrP6bLZW",
    "aws_region": "ap-northeast-1",
    "user_pool_client_id": "4i56nhb28ftc251lp6fdn92r6e",
    "identity_pool_id": "ap-northeast-1:743f1a0f-b4dc-4f91-89e3-bd10b01f700e",
    "mfa_methods": [],
    "standard_required_attributes": [
      "email"
    ],
    "username_attributes": [
      "email"
    ],
    "user_verification_types": [
      "email"
    ],
    "mfa_configuration": "NONE",
    "password_policy": {
      "min_length": 8,
      "require_lowercase": true,
      "require_numbers": true,
      "require_symbols": true,
      "require_uppercase": true
    },
    "unauthenticated_identities_enabled": true
  },
  "data": {
    "url": "https://jx3glrsb7na3dfhorqyb3hl5ne.appsync-api.ap-northeast-1.amazonaws.com/graphql",
    "aws_region": "ap-northeast-1",
    "api_key": "xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx",
    "default_authorization_type": "API_KEY",
    "authorization_types": [
      "AMAZON_COGNITO_USER_POOLS",
      "AWS_IAM"
    ],
    "model_introspection": {
      "version": 1,
      "models": {
        "Todo": {
          "name": "Todo",
          "fields": {
            "id": {
              "name": "id",
              "isArray": false,
              "type": "ID",
              "isRequired": true,
              "attributes": []
            },
            "content": {
              "name": "content",
              "isArray": false,
              "type": "String",
              "isRequired": false,
              "attributes": []
            },
            "createdAt": {
              "name": "createdAt",
              "isArray": false,
              "type": "AWSDateTime",
              "isRequired": false,
              "attributes": [],
              "isReadOnly": true
            },
            "updatedAt": {
              "name": "updatedAt",
              "isArray": false,
              "type": "AWSDateTime",
              "isRequired": false,
              "attributes": [],
              "isReadOnly": true
            }
          },
          "syncable": true,
          "pluralName": "Todos",
          "attributes": [
            {
              "type": "model",
              "properties": {}
            },
            {
              "type": "auth",
              "properties": {
                "rules": [
                  {
                    "allow": "public",
                    "provider": "apiKey",
                    "operations": [
                      "create",
                      "update",
                      "delete",
                      "read"
                    ]
                  }
                ]
              }
            }
          ],
          "primaryKeyInfo": {
            "isCustomPrimaryKey": false,
            "primaryKeyFieldName": "id",
            "sortKeyFieldNames": []
          }
        }
      },
      "enums": {},
      "nonModels": {}
    }
  },
  "version": "1.1"
}

This is the configuration information from when I deployed, and the json file is broadly divided into two parts:

  • auth: Configuration information related to Cognito, AWS’s authentication service
  • data: Configuration information related to App Sync, AWS’s GraphQL service

By downloading the configuration information for the backend services built with Amplify like this,
you can access the backend services and develop against them even when running Next.js in your local environment.

*The api_key has been replaced with a dummy value.

If you open the /app/page.tsx file, you’ll see the following code:

page.tsx

import outputs from "@/amplify_outputs.json";


Amplify.configure(outputs);

This is what enables Next.js to connect to the Amplify backend services.

This file itself is not needed at deployment time, so it’s listed in .gitignore.

# amplify
.amplify
amplify_outputs*
amplifyconfiguration*

Add a delete button to the screen

Now we’re ready to develop in the local environment.

Open the /app/page.tsx file and start writing code.

page.tsx

  function createTodo() {
    client.models.Todo.create({
      content: window.prompt("Todo content"),
    });
  }

+   function deleteTodo(id: string) {
+     client.models.Todo.delete({ id });
+   }

  return (
    <main>
      <h1>My todos</h1>
      <button onClick={createTodo}>+ new</button>
      <ul>
        {todos.map((todo) => (
-           <li key={todo.id}>{todo.content}</li>
+           <li key={todo.id} style={{ display: 'flex', justifyContent: 'space-between' }}>
+             {todo.content}
+             <button onClick={() => deleteTodo(todo.id)}>delete</button>
+             </li>
        ))}
      </ul>
      <div>
        🥳 App successfully hosted. Try creating a new todo.
        <br />
        <a href="https://docs.amplify.aws/nextjs/start/quickstart/nextjs-app-router-client-components/">
          Review next steps of this tutorial.
        </a>
      </div>
    </main>
  );
}

We created a delete button, and when the delete button is clicked, deleteTodo deletes the Todo with the corresponding ID.

Verify behavior

Now that the delete button has been created, start Next.js locally and verify that it works.

npm run dev

If clicking delete removes the item as shown in the screen below, you’re good to go. (I also deleted the blank Todo at this point.)

Image from Gyazo

Reflect changes in production

Since we’ve confirmed it works in the local environment, let’s reflect the changes in production.
The repository and AWS Amplify are already connected, and the contents of the main branch are always deployed to production.
So all you need to do is commit to the main branch with the following commands, and the changes will be reflected in production.

git add .
git commit -m "add delete button"
git push origin HEAD

If you go back to the Amplify console, you’ll see that a deployment is in progress.

Image from Gyazo

The Amplify console also provides a deployment history.
It looks like it finally finished. Five minutes... surprisingly long.

Image from Gyazo

Access the production URL, and if the delete button appears and clicking it deletes the item, everything is OK.

Data management

Here are a couple of convenient features in AWS Amplify.

On the Data manager page, you can view the Todos that were displayed in Next.js earlier. (You can not only view them, but also add and delete them.)

In many development scenarios, you’ll need sample data, and you can create it here before proceeding with development.

Image from Gyazo

Also, on the API playground page, you can write GraphQL code to retrieve data.

You can try out data-fetching queries here before proceeding with development in your local environment.

Image from Gyazo

Deleting the sample app

If you leave it running, AWS charges will accrue, so we’ll delete it this time.

Select “General settings” from the left menu to display the app deletion screen.

Image from Gyazo

Conclusion

In this article, we followed the official documentation to deploy Next.js using AWS Amplify.

You should now have a sense that you can deploy to AWS in a relatively short time and with minimal knowledge, even if you’re not deeply familiar with AWS.

For PoC and other new app development, you can use AWS Amplify to quickly provide demo screens.

Amplify also makes it easy to integrate with Cognito, so I hope to introduce authentication mechanisms using Amplify in another article in the future.

Xでシェア
Facebookでシェア
LinkedInでシェア

Questions about this article 📝

If you have any questions or feedback about the content, please feel free to contact us.
Go to inquiry form