amplify-hosting
amplify-hosting copied to clipboard
Next.js Preview mode doesn't work on Amplify?
Please describe which feature you have a question about?
Do I have to set the Next.js version to a specific value(version) to implement the Next.js preview mode?
I trying to implement the Next.js Preview mode. Next.js Preview mode is refer to: https://nextjs.org/docs/advanced-features/preview-mode
But Next.js Preview mode doesn't work on Amplify. ( I checked Preview mode is correct working on Vercel or local.) Next.js version of my app is 11.1.3. And Next.js version of Amplify (Build image settings) is 11. And webpack5.
Working point
- I checked Next.js API Rpute is working because Cookie was set in the header.
- I checked
getStaticProps
is working because logic in thegetStaticProps
was called when request came.
Not working point
-
context.preview
isundefined
in thegetStaticProps
Related issues:https://github.com/aws-amplify/amplify-console/issues/2532
Provide additional details none
What AWS Services are you utilizing? Amplify Console, Amplify CLI
Provide additional details e.g. code snippets I'm trying with the code below, but the browser shows "none none".
preview page (pages/preview.js)
export default function Preview({ message, timestamp }) {
return message + " " + timestamp;
}
export async function getStaticProps(context) {
// If you request this page with the preview mode cookies set:
//
// - context.preview will be true
// - context.previewData will be the same as
// the argument used for `setPreviewData`.
return {
props: {
message: context.preview ? context.previewData.message : "none",
timestamp: context.preview ? context.previewData.timestamp : "none",
},
};
}
preview api (api/preview.js)
// A simple example for testing it manually from your browser.
// If this is located at pages/api/preview.js, then
// open /api/preview from your browser.
export default function handler(req, res) {
res.setPreviewData({
message: "Hey, this is a preview",
timestamp: new Date().toISOString(),
});
res.redirect("/preview");
}
Hi! I understand the cause.
The cause seemed to be cookies(of preview mode) were not allowed in the origin request on CloudFront by default.
So I have a question.
- How should I set CloudFront to control cookies (add / delete cookies) from Next.js API Route? I think I probably have to disable the cookies(of preview mode) cache and send it to the origin.
- Is there any reason why Amplify set CloudFront to "Legacy cache settings" than "Cache policy and origin request policy (recommended)" by default?
please give me some advice or new information!
Did you manage to find a solution to this @skrg-kotani ? I tried going with Cache policy and origin request policy (recommended)
option, and then selecting Amplify
option for Cache Policy
for all paths except _next/static/*
and static/*
, which seemed to fix the problem.
But unfortunately the settings seem to re-set on every new build. I'm on Next.js 11.1.2.
I have the same problem. I hope this issue will be solved.
I have the same problem. Any recommendation or workaround?

@biiishal
Thanks for your advice!
For me, By adding just two cookies to all paths except _next/static/*
and static/*
, which seemed to fix the problem.
Automated workaround.... use SNS on build success to trigger a lambda that updates the distribution behaviors so the preview cookies work.
- Create SNS notification for builds
Easiest way to do this is add email notifications through the Amplify console and snag the ARN for the SNS topic that triggers those emails.
- Create a lambda function that updates the cloudfront distribution after the build
I added this lambda to an existing serverless framework project but you can create an ad-hoc lambda function, too. If you go the ad-hoc route then add a Layer that has @aws-sdk/client-cloudfront
installed and use that in the function.
IAM
{
Effect: "Allow",
Action: ["cloudfront:GetDistribution", "cloudfront:UpdateDistribution"],
Resource: ["<ARN FOR YOUR DISTRIBUTION>"],
}
serverless.ts function definition
wwwBuildEvent: {
handler: "src/sns-events/www-build-events/handler.handler",
events: [
{
sns: "<ARN FOR SNS TOPIC>",
},
],
},
Handler
import {
CloudFrontClient,
UpdateDistributionCommand,
GetDistributionCommand,
GetDistributionCommandInput,
UpdateDistributionCommandInput,
CacheBehavior,
} from "@aws-sdk/client-cloudfront";
const updateDistributionForNextPreview = async (distributionId: string) => {
const client = new CloudFrontClient({});
const input: GetDistributionCommandInput = {
Id: distributionId,
};
const getDistCmdStr = new GetDistributionCommand(input);
const getDistResp = await client.send(getDistCmdStr);
// https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html
const amplifyCachePolicyId = "2e54312d-136d-493c-8eb9-b001f22f67d2";
const updateInput: UpdateDistributionCommandInput = {
DistributionConfig: {
...getDistResp.Distribution.DistributionConfig,
DefaultCacheBehavior: {
...getDistResp.Distribution.DistributionConfig.DefaultCacheBehavior,
MinTTL: undefined,
ForwardedValues: undefined,
MaxTTL: undefined,
DefaultTTL: undefined,
CachePolicyId: amplifyCachePolicyId,
},
CacheBehaviors: {
Quantity:
getDistResp.Distribution.DistributionConfig.CacheBehaviors.Quantity,
Items:
getDistResp.Distribution.DistributionConfig.CacheBehaviors.Items.map(
(cacheBehavior): CacheBehavior => {
if (
cacheBehavior.PathPattern === "_next/static/*" ||
cacheBehavior.PathPattern === "static/*"
) {
return cacheBehavior;
}
return {
...cacheBehavior,
MinTTL: undefined,
ForwardedValues: undefined,
MaxTTL: undefined,
DefaultTTL: undefined,
CachePolicyId: amplifyCachePolicyId,
};
}
),
},
},
Id: getDistResp.Distribution.Id,
IfMatch: getDistResp.ETag!,
};
const updateDistCmdStr = new UpdateDistributionCommand(updateInput);
const updateDistResp = await client.send(updateDistCmdStr);
return updateDistResp;
};
exports.handler = async (event, context) => {
const sns = event.Records[0].Sns.Message;
if (!sns.includes("build status is SUCCEED")) {
return sns;
}
// update cloudfront distribution so that next preview works
const distributionId = "<YOUR DISTRIBUTION ID>";
await updateDistributionForNextPreview(distributionId);
return sns;
};
We also had issues with the environment variables not working. We tried checking process.env.IS_PREVIEW
but the amplify env variable overrides do not work yet with Next.
After following the steps in this issue https://github.com/aws-amplify/amplify-hosting/issues/1987 to expose the variables and remove our dependency on the overrides by checking AWS_BRANCH instead AND the above automation our previews are working great.
Just in case anyone else arrives on this issue the same way we did, and saves them an hour.
If you're finding the previews aren't working in Chrome (Incognito), it's because Incognito blocks 3rd party cookies by default. If you head into Preferences and Allow All Cookies (!) then it works.
Funnily enough MS Edge does not have the same behaviour and allows the cookie.
My NextJS 13 SSR app is setting cookies on my local machine properly but the response headers are not returning with set cookie for __next_preview_data
when i deploy on amplify. does anyone have any idea why this is happening?
Amplify SSR

Local System

Hi all. I have successfully tested Next.js Preview Mode today with the contentful example so this issue can be closed.
Note the build config I used to ensure the server-side runtime has access to the environment variables.
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- env | grep -e CONTENTFUL_SPACE_ID -e CONTENTFUL_ACCESS_TOKEN -e CONTENTFUL_PREVIEW_ACCESS_TOKEN -e CONTENTFUL_PREVIEW_SECRET -e CONTENTFUL_REVALIDATE_SECRET >> .env.production
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
⚠️COMMENT VISIBILITY WARNING⚠️
Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.