aws-amplify / amplify-hosting

AWS Amplify Hosting provides a Git-based workflow for deploying and hosting fullstack serverless web applications.
https://aws.amazon.com/amplify/hosting/
Apache License 2.0
456 stars 115 forks source link

Next.js APP router SSG #3872

Closed lwang-79 closed 1 week ago

lwang-79 commented 9 months ago

Before opening, please confirm:

App Id

d1fn6pdw73hgp

AWS Region

ap-southeast-1

Amplify Hosting feature

Build settings

Frontend framework

Next.js

Next.js version

13.4.12

Next.js router

App Router

Describe the bug

I tried to convert the Next.js SSR to SSG by following the FAQ. However the app platform and branch framework always change back to Web dynamic and Next.js SSR during the build.

After I added command - envCache --set stackInfo "", the platform and framework seems not change back, but the frontend build doesn't start because next export does not work with App Router.

- error "next export" does not work with App Router. Please use "output: export" in next.config.js https://nextjs.org/docs/advanced-features/static-html-export

If I change to next build and configure the "output: export" in next.config.js, the build works locally but Amplify changes the app to web platform and SSR.

Expected behavior

Can deploy Next.js App Router SSG app.

Reproduction steps

  1. Deploy a App Router SSR app.
  2. Try to convert it to SSG.

Build Settings

version: 1
backend:
  phases:
    build:
      commands:
        - '# Execute Amplify CLI with the helper script'
        - envCache --set stackInfo ""
        - amplifyPush --simple
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: out
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

Log output

``` # Put your logs below this line # with next build 2023-12-21T08:16:16.142Z [INFO]: Starting SSR Build... 2023-12-21T08:17:11.606Z [ERROR]: Error: Command failed with exit code 1: node_modules/.bin/next build # with next export 2023-12-21T08:10:06.483Z [WARNING]: - warn "next export" is no longer needed when "output: export" is configured in next.config.js https://nextjs.org/docs/advanced-features/static-html-export 2023-12-21T08:10:06.484Z [INFO]: Export successful. Files written to /codebuild/output/src856227934/src/betom/out 2023-12-21T08:10:06.492Z [INFO]: # Completed phase: build 2023-12-21T08:10:06.510Z [INFO]: ## Build completed successfully 2023-12-21T08:10:06.511Z [INFO]: # Starting caching... 2023-12-21T08:10:06.521Z [INFO]: # Creating cache artifact... 2023-12-21T08:10:16.747Z [INFO]: # Created cache artifact 2023-12-21T08:10:16.830Z [INFO]: # Uploading cache artifact... 2023-12-21T08:10:20.416Z [INFO]: # Uploaded cache artifact 2023-12-21T08:10:20.492Z [INFO]: # Caching completed 2023-12-21T08:10:20.701Z [ERROR]: !!! CustomerError: Artifact directory doesn't exist: out ```

Additional information

No response

tonynechar commented 9 months ago

I am having the same issue. @calavera any tips? Thanks in advance.

tonynechar commented 9 months ago

I think I found a solution:

Hope this helps you with your case too

datnguyennnx commented 7 months ago

Amplify detect config "build" in package.json is "next build" => we have SSR app. Then Nextjs build project and export folder ".next" for deployment.

Your SSG app when builded sucess => export folder out for deployment.

Bug: When Amplify detect your app is SSR. After build success they point to ".next" for deployment => Build failed. But your app is SSG, they export at "out" folder. So your change config build: "next build" to build: "next build and next export" => Amplify detect your app is SSG. => Correct. This case is no match with Nextjs 14.

Reason: because Nextjs 14 is change way to build SSG page. They remove "next build && next export" ( => Amplify detect SSG app) to "next build" and add line output: "export" in next.config.js

Way i fixed that: 

Check it out here:

Key: Make sure Amplify detect your app build is SSG.

martijnwiekens commented 3 months ago

I was unable to convince Amplify that my branch is not a SSR app. I have 2 branches, both of them SSG. My main branch is Next 13, my test branch is Next 14. I don't use the app router but the "old" pages system, but Next 14 only has the export in the next.config. The config of the Amplify app has the right SSG config, but still Amplify wants the build the new branch with SSR.

The only way I could get this working was with a little hack. I added this to the amplify.yml build commands (before the npm build command): sed -i "s/process.exit(1)/process.exit(0)/g" node_modules/next/dist/cli/next-export.js This way the export command from next doesn't exit with error level 1 and break the deployment process. And amplify-s detection systems keep seeing it as a SSG app.

mauerbac commented 3 months ago

We are currently working on this issue! Stay tuned

renchris commented 3 months ago

I am trying to find the correct absolute path to my code files, but I cannot find my original code files, whether I use process.cwd() or __dirname, for my NextJS App Router application on AWS Amplify (Framework: Next.js - SSR, Platform: WEB_COMPUTE)

My migrate.ts file in my drizzle folder at the root of my project cannot correctly get the relative path (or absolute path with resolve process.cwd() / __dirname) to my _journal.json file in my drizzle/migrations/meta folder

My application is fine with my local pnpm dev development pnpm build; pnpm start production build but not the Amplify build

// drizzle/migrate.ts
'use server'

import { migrate } from 'drizzle-orm/libsql/migrator'
import { resolve } from 'node:path'
import { getNamedDB } from './db'

const migrateDB = async (organizationName: string) => {
  const db = await getNamedDB(organizationName)
  const migrationsFolder = resolve(process.cwd(), './drizzle/migrations')
  await migrate(db, { migrationsFolder })
}

export default migrateDB

When I see what contents I have from process.cwd(), in my local production build, I see my entire project structure and files as usual, but in my Amplify build, I do not and instead see something similar to the build artifacts

function logFullPathToHere(cwd: string): void {
  const parts = cwd.split(path.sep)
  let fullPath = ''

  parts.forEach((part, index) => {
    fullPath = path.join(fullPath, part)
    console.log(' '.repeat(index * 2) + fullPath)
  })
}

logFullPathToHere(process.cwd())
  | 2024-06-28T08:30:29.842Z | process.cwd() folder contents: [
-- | -- | --
  | 2024-06-28T08:30:29.842Z | '.env',
  | 2024-06-28T08:30:29.842Z | '.next',
  | 2024-06-28T08:30:29.842Z | 'amplify-compute-bundle-output',
  | 2024-06-28T08:30:29.842Z | 'node_modules',
  | 2024-06-28T08:30:29.842Z | 'package.json',
  | 2024-06-28T08:30:29.842Z | 'public',
  | 2024-06-28T08:30:29.842Z | 'server.js'
  | 2024-06-28T08:30:29.842Z | ]
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - corepack enable
        - pnpm install --frozen-lockfile
        - pnpm setup-env
        - pnpm migrate
    build:
      commands:
        - pnpm build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - .next/cache/**/*
      - node_modules/**/*

How may I locate and access my project files from my NextJS App Router SSR Amplify built application?

mauerbac commented 1 week ago

Hello folks - this has been addressed!

You can convert an SSR App to SSG for NextJS 14+ applications. Look at the updated docs here -> https://docs.aws.amazon.com/amplify/latest/userguide/deploy-nextjs-app.html#build-setting-detection-ssg-14

You would need to commit a change in their nextConfig with `output: 'export' and Amplify Hosting will automatically switch to SSG for you!

github-actions[bot] commented 1 week ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.