Introduction#

GitHub this note shows different way to host a website developed in NextJS

  • NextJS static export
  • Static website (SSG)
  • Hybrid website (SSR)

Next.js enables starting as a static site or Single-Page Application (SPA), then later optionally upgrading to use features that require a server.

[!IMPORTANT] For the Manual deployment, please select Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment), and then select Manual deployment.

Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)

then

Manual deployment

Setup Project#

The package.json file

{
"name": "react-amplify-hosting-demo-1",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.0.2"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"eslint": "^8",
"eslint-config-next": "14.0.2"
}
}

Please update the next.config.js file for nextjs static export

/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export'
}
module.exports = nextConfig

Amplify CLI - Manual Hosting - SSG#

In this case, this is a static website (SSG) developed in NextJS. Amlify hosts this website using S3 and CloudFront. It will copy build output from the out folder to S3 and the upload to a CloudFront Distribution. First init a new amplify project by cli

amplify init

Then please select react and out directory for distrbiution. Next, add hosting and please select firs option with manual deployment

amplify add hosting

Finally publish

amplify publish

This option does not expicitly show a new S3 and CloudFront Distribution

Amplify CLI - CloudFront and S3 - SSG#

amplify init

Then please select react and out directory for distrbiution. Next, add hosting and please select second option with CloudFront and S3

amplify add hosting

Finally publish

amplify publish

This option does expicitly show a new S3 and CloudFront Distribution

Github - Amplify Hosting - SSG#

Check the package.json for next 14

{
"name": "react-amplify-hosting-demo-1",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.0.2"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"eslint": "^8",
"eslint-config-next": "14.0.2"
}
}

Check the next.config.js does not have export output as for the static (SSG)

/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export'
}
module.exports = nextConfig

Please note that, for next 12, we are still using in the package.json and without the output export in the next.config.js

"build": "next build && next export",

GitHub - Amplify Hosting - SSR#

Check the package.json

{
"name": "react-amplify-hosting-demo-1",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.0.2"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"eslint": "^8",
"eslint-config-next": "14.0.2"
}
}

Check the next.config.js does not have export output as for the static (SSG)

const { withContentlayer } = require('next-contentlayer')
const nextConfig = {
experimental: {
serverActions: true
},
reactStrictMode: true,
swcMinify: true,
images: {
unoptimized: true
},
output: 'standalone'
}
module.exports = withContentlayer(nextConfig)

Amplify Hosting - CDK Stack - SSR#

Another way is to using an CDK Stack to deploy an app

  • Connect to github via secret or token
  • Amplify CI/CD pipeline to deploy the app
import { SecretValue, Stack, StackProps, aws_codebuild } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as Amplify from '@aws-cdk/aws-amplify-alpha'
interface AmplifyHostingProps extends StackProps {
owner: string
repository: string
token: string
envVariables: any
commands: any
}
export class AmplifyHosting extends Stack {
constructor(scope: Construct, id: string, props: AmplifyHostingProps) {
super(scope, id, props)
const amplify = new Amplify.App(this, 'CDKForAamplifyHosting', {
sourceCodeProvider: new Amplify.GitHubSourceCodeProvider({
owner: props.owner,
repository: props.repository,
oauthToken: SecretValue.secretsManager(props.token)
// oauthToken: SecretValue.unsafePlainText(props.token),
}),
buildSpec: aws_codebuild.BuildSpec.fromObjectToYaml({
version: '1.0',
frontend: {
phases: {
preBuild: {
commands: ['npm ci']
},
build: {
commands: props.commands
}
},
artifacts: {
baseDirectory: '.next',
files: ['**/*']
},
cache: {
path: ['node_modules/**/*']
}
}
}),
platform: Amplify.Platform.WEB_COMPUTE,
environmentVariables: props.envVariables
})
amplify.addBranch('main', { stage: 'PRODUCTION' })
}
}

More complicated build.yaml script

Insights#

Quote from [HERE]

Deploy and host your app using either Amplify Console or Amazon CloudFront/S3. The Amplify Console offers fully managed hosting with features such as instant cache invalidation and atomic deploys. For more control with setting up a CDN and hosting buckets, use CloudFront and S3.

Amazon S3 and Amazon Cloudfront. The Amplify CLI provides you the option to manage the hosting of your static website using Amazon S3 and Amazon Cloudfront directly as well. Following are the concepts you would encounter when adding S3 & Cloudfront as a hosting option for your Amplify project.

Reference#