Incorrect Redirect Behavior for Dynamic Routes in Next.js 14 (Pages Router) App on AWS Amplify
Environment information
Framework: Next.js 14
Routing system: Pages Router (not App Router)
Build output: .next directory, no index.html
Hosting: AWS Amplify
Build commands:
version: 1
applications:
- appRoot: .
frontend:
phases:
preBuild:
commands:
- nvm install 20.9.0
- nvm use 20.9.0
- node -v
- npm ci
build:
commands:
- npm ci
- npm run build
- rm -rf node_modules/canvas
- node scripts/generate-amplify-rewrites.js
- echo "AMPLIFY_APP_ID=$AMPLIFY_APP_ID"
- node scripts/update-amplify-rewrites.js
- npm run postbuild || echo "no postbuild"
- rm -rf .next/cache
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
customHeaders:
- pattern: '**/*'
headers:
- key: 'Cache-Control'
value: 'public, max-age=0, must-revalidate'
Describe the bug
Hi,
I’m experiencing an issue with dynamic routes not resolving correctly in my Next.js 14 app hosted on AWS Amplify.
For example:
✅ Expected behavior: Visiting the short link
https://abc.amplifyapp.com/share?id=E2EBAF72ED0
should redirect to
https://abc.amplifyapp.com/proposals/8f723ad7-e14f-4ca9-ad58-6fa4b60abcec/preview?insurance_type=comprehensive
❌ Actual behavior: Instead, it redirects to
https://abc.amplifyapp.com/proposals?insurance_type=comprehensive
The dynamic route segment (/8f723ad7-e14f-4ca9-ad58-6fa4b60abcec/preview) is being truncated or dropped by Amplify’s static hosting layer, even though the route exists and works perfectly in local Next.js development.
What I’ve already tried:
Explicitly added rewrite rules like:
{ "source": "/proposals/:proposal_id/preview", "status": "200", "target": "/proposals/:proposal_id/preview" }, { "source": "/proposals/:proposal_id/preview/index", "status": "200", "target": "/proposals/:proposal_id/preview/index" }
Verified that the dynamic route /pages/proposals/[proposal_id]/preview/index.js exists.
Confirmed that the same route structure works correctly in local dev and static export builds.
Issue Summary: Even after adding specific rewrites, Amplify Hosting appears to interpret /proposals/:proposal_id/preview as /proposals, discarding the dynamic segments and query parameters.
Additional Concern:
Currently, I’m forced to manually generate and include rewrites for every static and nested path in the app. This includes dozens of entries like:
{ "source": "/car-insurance", "status": "200", "target": "/car-insurance" }, { "source": "/life-insurance", "status": "200", "target": "/life-insurance" }, ...
This seems unnecessary because:
My app uses Next.js 14 with the Pages Router — it doesn’t generate a traditional index.html per page.
Next.js automatically handles routing via pages/ structure and dynamic route segments like [proposal_id] or [query].js.
On most platforms (Vercel, Netlify, etc.), these routes resolve automatically without defining every rewrite manually.
So I’d like to understand why Amplify requires manually defining each path instead of automatically serving the correct Next.js route.
Reproduction steps
Request:
Please confirm how to properly handle Next.js dynamic routes ([id], [slug], etc.) in Amplify Hosting.
Is there a recommended wildcard rewrite pattern or regex-based rule to support all Next.js routes without defining each one manually?
Can you confirm if the lack of index.html (in Next.js 14 pages output) affects Amplify’s static route resolution?
Hi @HarshitSrivastava007,
Thanks for reporting this issue! I can see you're experiencing problems with dynamic routes in your Next.js 14 Pages Router app on Amplify Hosting.
First, I want to note that this issue has been filed in the amplify-backend repository, which is specifically for Amplify Gen 2 backend infrastructure (data, auth, functions). Since your issue is related to hosting and deployment of a Next.js application, it should be filed in the amplify-hosting repository instead. The team there will be better equipped to help with SSR deployment and routing issues.
That said, here are some observations and suggestions:
Potential Issues:
-
SSR Configuration: Your build config uses
.nextas the artifact directory, which is correct for Next.js SSR. However, Amplify should auto-detect Next.js and handle dynamic routes automatically. The fact that you need manual rewrites for every route suggests the SSR detection might not be working correctly. -
Redirect vs Route Resolution: The issue you're describing involves a redirect from
/share?id=Xto/proposals/{uuid}/preview. If this redirect is happening server-side (in your Next.js code), the target URL should work directly without additional rewrites. The problem might be in how Amplify's routing layer is handling the redirected URL. -
Manual Rewrite Scripts: The custom scripts (
generate-amplify-rewrites.jsandupdate-amplify-rewrites.js) you're using suggest you're working around a deeper configuration issue. Next.js dynamic routes should work out-of-the-box on Amplify without manual rewrite generation.
Recommendations:
-
Transferring this issue to the amplify-hosting repository for proper support.
-
Verify your Next.js configuration: Ensure your
next.config.jsdoesn't have any conflicting settings that might interfere with SSR deployment. -
Check the build logs: Look for any warnings about SSR detection or routing configuration during the Amplify build process.
-
Consider using Next.js built-in redirects: Instead of custom rewrite scripts, use Next.js's built-in redirect functionality in
next.config.jsor middleware, which will work consistently across all environments. -
Review the deployment specification: Check the Amplify SSR deployment documentation to ensure your app follows the expected patterns.