How to Deploy Next.js to AWS S3 with GitHub Actions Guide
By Braincuber Team
Published on April 7, 2026
This complete tutorial walks you through automating your Next.js website deployments to AWS S3 using GitHub Actions. Instead of manually building and uploading files every time you make a change, this step by step guide shows you how to set up continuous deployment so that every push to your main branch automatically builds your Next.js app and syncs it to S3. Whether you are deploying a static site, a Jamstack app, or a fully exported Next.js project, this beginner guide covers everything from S3 bucket configuration to GitHub Secrets management.
What You'll Learn:
- How to configure Next.js to export static files with next build and next export
- How to create and configure an S3 bucket for static website hosting
- How to manually deploy a Next.js build to S3 for initial setup
- How to create a GitHub Actions workflow that builds your Next.js project automatically
- How to configure AWS credentials in GitHub Secrets for secure deployment
- How to sync your built files to S3 using the AWS CLI in a GitHub Action step
- How to set up CloudFront cache invalidation for instant content updates
Continuous Deployment
Every push to your main branch triggers an automatic build and deployment. No manual uploads or server management required.
AWS S3 Static Hosting
Host your entire website on S3 object storage with global availability, low cost, and built-in HTTP access configuration.
GitHub Actions Workflow
Automate your entire build and deploy pipeline with a YAML workflow file that runs on every push to your main branch.
Secure Credential Management
Store AWS access keys in GitHub Secrets to keep credentials safe. Keys are masked in logs and never exposed in code.
Prerequisites
You need a GitHub account, an AWS account, Node.js and npm or yarn installed locally, and basic familiarity with Next.js and Git workflows.
What Are GitHub Actions and Continuous Deployment
GitHub Actions is a free service from GitHub that allows you to automate code tasks. You can use it to run tests, send notifications, build projects, and deploy websites automatically based on your existing workflows. Actions are defined in YAML workflow files stored in your repository under .github/workflows/.
Continuous Deployment (CD) is the practice of maintaining code in a releasable state and deploying that code automatically or in short cycles. In this tutorial, every time a new update is pushed or merged to the primary Git branch (main), your website will automatically build and deploy to S3.
AWS S3 (Simple Storage Service) is an object storage service from AWS that allows you to store files in the cloud and serve them as a website. By uploading HTML, CSS, JavaScript, and image files as objects, you can configure S3 to serve them via HTTP requests, effectively hosting an entire static website.
How to Set Up a New Next.js Project on GitHub
The first step in this beginner guide is creating a Next.js project and configuring it to export static files. Start by bootstrapping a new app using the default Next.js template.
# Create the project
yarn create next-app my-static-website
# or
npx create-next-app my-static-website
# Navigate into the project
cd my-static-website
# Start the development server
yarn dev
# or
npm run dev
How to Configure Next.js for Static Export
To host on S3, you need static HTML files. Update your package.json build script to run next export after the build, which compiles your Next.js app into static files in the out directory.
{
"scripts": {
"dev": "next dev",
"build": "next build && next export",
"start": "next start"
}
}
Test the static export by running the build command. Once finished, look inside the out directory to see all the static files of your website.
yarn build
# or
npm run build
# Check the output directory
ls out/
How to Push the Project to GitHub
Create a new repository in your GitHub account, then follow the instructions to add your existing project. Push your code to the main branch so it is ready for GitHub Actions.
How to Manually Create and Deploy to an S3 Bucket
Before automating the deployment, it is important to understand the manual process. This step by step guide section walks you through creating an S3 bucket, configuring it for website hosting, and uploading your build files.
Create a New S3 Bucket
Log into your AWS account, navigate to the S3 service, and click Create Bucket. Choose a unique name that will be used as your website endpoint.
Enable Static Website Hosting
In the bucket properties, go to Static website hosting and enable it. Set the index document to index.html and the error document to 404.html.
Configure Bucket Permissions
Unblock public access settings and add a bucket policy that allows s3:GetObject for all objects. This is required for the website to be publicly accessible.
Upload Build Files
Run npm run build locally, then upload all files from the out directory into your S3 bucket using the AWS console or CLI.
Once the files are uploaded and the bucket is configured for website hosting, you can access your project live on the web using the S3 website endpoint URL.
How to Create a GitHub Action Workflow to Build Your Next.js Project
Now that you understand the manual process, let us automate it. Navigate to the Actions tab of your GitHub repository and click on set up a workflow yourself.
GitHub provides a starting template. Make the following changes to tailor it for continuous deployment:
name: CD
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
This workflow triggers a new Ubuntu instance and checks out your code every time there is a push to the main branch. Now add the build steps.
name: CD
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
- run: npm install -g yarn
- run: yarn install --frozen-lockfile
- run: yarn build
- uses: actions/setup-node@v1
with:
node-version: 12
- run: npm ci
- run: npm run build
| Step | Purpose |
|---|---|
| actions/checkout@v2 | Checks out your repository code on the runner |
| actions/setup-node@v1 | Installs Node.js on the runner so npm and node commands work |
| npm install -g yarn | Installs Yarn globally (Yarn projects only) |
| yarn install --frozen-lockfile | Installs dependencies using the lock file to avoid unexpected upgrades |
| npm ci | Clean install using package-lock.json (npm projects only) |
| yarn build / npm run build | Compiles Next.js into static files in the out directory |
Commit this workflow file to your main branch. This triggers a new workflow run that you can monitor in the Actions tab. Navigate into the run, select your workflow, and verify that all steps completed including the build.
How to Configure GitHub Actions to Deploy to S3
Now that your project builds automatically, you need to sync the output to S3. This complete tutorial section covers configuring AWS credentials and running the sync command.
How to Generate AWS Access Keys
Navigate to Security Credentials
In the AWS console, click your user menu and select My Security Credentials.
Create Access Key
Select Create access key. This generates two values: the Access key ID and the Secret access key. Save both values immediately since the secret key cannot be retrieved again.
Never Commit AWS Keys to Code
Never include your Access Key or Secret Key directly in your code or workflow file. This could lead to someone compromising your AWS credentials. Always use GitHub Secrets to store sensitive values.
How to Add AWS Keys as GitHub Secrets
In your GitHub repository, navigate to Settings, then Secrets, and select New secret. Add your AWS keys using the following secret names:
| GitHub Secret Name | Value |
|---|---|
| AWS_ACCESS_KEY_ID | Your AWS Access Key ID |
| AWS_SECRET_ACCESS_KEY | Your AWS Secret Access Key |
How to Add the Deployment Steps to Your Workflow
Add the AWS credentials configuration and S3 sync command to your workflow file. The aws-actions/configure-aws-credentials action sets up your AWS credentials so the AWS CLI can authenticate.
name: CD
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
- run: npm install -g yarn
- run: yarn install --frozen-lockfile
- run: yarn build
- uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- run: aws s3 sync ./out s3://your-bucket-name
Replace your-bucket-name with the actual name of your S3 bucket. The aws s3 sync command compares your local out directory with the bucket and uploads only the changed files, making deployments fast and efficient.
How to Test the Automated Deployment
Commit your workflow changes to the main branch. The action is automatically triggered, builds your project, and syncs it to S3. You can monitor the run in the Actions tab.
To verify the deployment works end to end, make a code change such as updating the homepage title in pages/index.js:
// pages/index.js
My Next.js! Site
Commit this change and watch the workflow trigger automatically. Once the workflow finishes, refresh your S3 website URL to see the updated content live.
How to Set Up CloudFront for Your S3 Website
While S3 can host your website directly, using Amazon CloudFront as a CDN in front of S3 provides faster global delivery, HTTPS support, and custom domain capabilities.
How to Invalidate CloudFront Cache
If your S3 website is behind CloudFront, you need to invalidate the cache after each deployment so visitors see the latest changes. Add this step to your workflow after the S3 sync:
- run: |
aws cloudfront create-invalidation \
--distribution-id YOUR_DISTRIBUTION_ID \
--paths "/*"
Advanced: Pull Request Deployments
For teams working on multiple features, you can set up a separate workflow that only runs on pull requests. This workflow can dynamically create a new S3 bucket based on the branch name and add a comment to the pull request with the preview URL.
name: PR Preview
on:
pull_request:
branches: [ main ]
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Build, deploy to branch-specific bucket,
# and comment URL on the PR
S3 Bucket Configuration Required
Before setting up the GitHub Action, make sure your S3 bucket is configured for static website hosting and that you have unblocked public access permissions on the bucket. Otherwise the action may fail when trying to sync files.
Frequently Asked Questions
How to use GitHub Actions to deploy a Next.js website to AWS S3?
Create a GitHub Actions workflow that checks out code, installs dependencies, runs next build and next export, configures AWS credentials, and syncs the out directory to your S3 bucket using aws s3 sync.
How to configure Next.js for static export to S3?
Update your package.json build script to "next build && next export". This compiles your Next.js app into static HTML files in the out directory that can be hosted on S3.
How to store AWS credentials securely in GitHub Actions?
Store your AWS Access Key ID and Secret Access Key as GitHub Secrets in your repository settings. Reference them in your workflow using ${{ secrets.AWS_ACCESS_KEY_ID }} syntax so they are never exposed in code.
What does aws s3 sync command do in deployment?
The aws s3 sync command compares your local out directory with the S3 bucket and uploads only files that are new or changed. This makes deployments fast and efficient by avoiding unnecessary uploads.
How to invalidate CloudFront cache after S3 deployment?
Add an aws cloudfront create-invalidation step to your workflow after the S3 sync. Use --distribution-id with your CloudFront distribution ID and --paths "/*" to invalidate all cached files.
Need Help with AWS and CI/CD?
Our experts can help you design, build, and automate your cloud deployment pipelines on AWS, Azure, and GCP.
