amplify-hosting
amplify-hosting copied to clipboard
Some pages becomes randomly white useing next.js with ISR.
Before opening, please confirm:
- [X] I have checked to see if my question is addressed in the FAQ.
- [X] I have searched for duplicate or closed issues.
- [X] I have read the guide for submitting bug reports.
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
App Id
d1bxok73m14yc9
Region
eu-north-1
Amplify Hosting feature
No response
Describe the bug
Randomly did we get white pages on the website which is using next.js. I have been debugging and do see that those pages have 0 bytes in the s3 bucket. Look at the photo. This happens randomly and 1 way to solve it is by removing the HTML file and it will be rebuilt and published.
I think that the invalidation is ok and that next.js revalidates the page successfully but when AWS pushes the file into s3 bucket it fail and I don't see any error logs on this and so on.
Expected behavior
Page to revalidated successfully and pushed into s3 bucket without that the file will be blank and have 0 bytes.
Reproduction steps
It's hard to reproduce. The only way I see is to trigger a lot of revalidations and check for blank pages.
Build Settings
next.js default
Additional information
No response
Hi @emilpriverrc 👋🏽 thanks for raising this issue. Can you provide a code snippet for how you're implementing ISR and also a screenshot of your next.config.js file while we investigate?
Sure! @hloriana and thanks for the quick reply! :D
next.config.js
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
module.exports = withBundleAnalyzer({
future: {
webpack5: true,
},
i18n: {
locales: ["en", "no", "de", "sv"],
defaultLocale: "en",
},
images: {
domains: [
"a list of domains. i hide for the screenshot"
],
deviceSizes: [320, 640, 750, 828, 1080, 1200, 1920, 2048, 2560, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256],
},
async rewrites() {
return [
{
source: '/sitemap-en.xml',
destination: '/api/sitemap-en',
},
{
source: '/sitemap-no.xml',
destination: '/api/sitemap-no',
},
{
source: '/sitemap-de.xml',
destination: '/api/sitemap-de',
},
]
},
async headers() {
return [
{
source: '/.well-known/apple-developer-merchantid-domain-association',
headers: [
{
key: 'Content-Type',
value: 'text/plain',
},
],
},
];
},
});
Example of getStaticProps:
export const getStaticProps: GetStaticProps = async ({ params, preview = false, locale }) => {
const { slug } = params as { slug: string };
const language = (locale)?.toUpperCase() ?? 'EN';
const primaryMenu = await getMenu(
locale === 'en' ? 'PRIMARY' : `PRIMARY___${language}`,
);
const secondaryMenu = await getMenu(
locale === 'en' ? 'SECONDARY' : `SECONDARY___${language}`,
);
const saleMenu = await getMenu(
locale === 'en' ? 'SALE' : `SALE___${language}`,
);
const footerMenu1 = await getMenu(
locale === 'en' ? 'FOOTER1' : `FOOTER1___${language}`,
);
const footerMenu2 = await getMenu(
locale === 'en' ? 'FOOTER2' : `FOOTER2___${language}`,
);
const socialMenu = await getMenu(
locale === 'en' ? 'SOCIAL' : `SOCIAL___${language}`,
);
const menu = {
primary: primaryMenu,
secondary: secondaryMenu,
sale: saleMenu,
footer1: footerMenu1,
footer2: footerMenu2,
social: socialMenu,
};
let [page] = await getPage(slug, language);
const posts = await getAllPosts(language);
const tags = await getAllTags(language);
const themeSettings = await getThemeSettings();
if (preview) {
page = await getPreviewPost(slug) as Page;
}
if (!page) {
return {
notFound: true,
revalidate: 60,
};
}
return {
props: {
menu,
page,
posts,
tags,
themeSettings,
translations: page?.translations?.map((translation) => ({
uri: translation?.slug ?? null,
locale: translation?.language?.code ?? null,
})) ?? [],
},
revalidate: 60,
};
};
Example of getStaticPaths
export const getStaticPaths: GetStaticPaths = async () => {
const pages = await getAllPages();
const paths = pages.map((page) => ({
params: {
slug: page.slug,
},
locale: page.language.slug,
}));
return {
paths,
fallback: 'blocking',
};
};
Something good to add to the issue is that we use next version 10.1.2
@emilpriverrc thank you for providing these details, we're taking a look.
Hello. Just wondering. Any update on this?
Hi again ✌️ we just got another site with exact same problem. This site is a copy on another page with same code and content just new amplify app.
Should I send you some id for amplify ?
Hi, we were also not able to reproduce this. Can you provide the logs for the ISR lambda function please? You can follow this FAQ guide to locate the logs: Access Lambda Edge Logs
Yes if you can provide that amplify app ID as well that would be helpful. When the app is first built, are the pages accessible? And is it only after the revalidation period that the files are 0kb?
Correct, It works fine after a build. It's first on revalidation this happens.
APP id: d335y2aqqe2ekl
Is it safe to post the logs here? Or can i send it to you in some other way?
I went through all the logs in cloud watch and the only thing I saw was that we loaded .env.production. But 0 errors and so on
Hi, we removed revalidation in getStaticProps and have not had any issues since then. Really looks like revalidation it's the problem
Hi, we do now get white pages when building project even without ISR added. Pages are added to the s3 bucket with 0 bytes in it
I might be experiencing a similar issue. Some of Next.js pages return 0 bytes and re-running 'aws amplify start-job' fixes the issue.
We have the same issue on multiple Next.js sites on different AWS accounts.
Some pages randomly is empty (0 bytes) after build. Deleted the branch in AWS Amplify and connected the branch again fixed the issue for now.
Any update on this?
Hi!
We also have the same issue.
How we can get that behavior:
- Create a Next.js page with revalidation every X minutes
- At
getStaticProps
of your page, do some call to an external resource that can be unavailable (high traffic, network failure, random crashes) and throw an error. - Next.js fail to generate that page.
- For an unknown reason, Amplify assume that the result is a success-generated page and delivers it to S3/Cloudfront.
After months of investigations, we continue to don't understand why AWS Amplify works that way.
We only could "workaround" that issue by making the page return some content (text/string) instead of just throwing
the error to Next.js. But it is still useless.
Seems to us that Amplify makes 2 different tries to generate that page: one using the correct SSR and trying to generate a full static page. Other rendering the page/components with default values and relying on Next.js to do the hydration at the client-side with results of getStaticProps
.
- Is that correct?
- Why Amplify doesn't understand a failed revalidation and just discard the result? Keeping to clients the old and correct content.
I've also been experiencing this for months and haven't been able to find a suitable workaround to prevent 'Application Error' pages been shown on production when trying to load these 0kb pages. At this point I'm considering automating a script to periodically scan the S3 bucket for 0KB static pages and deleting them - however this feels like a horrible band-aid.
Facing same issue with nextjs using SSR. blank page coming sometimes specially when doing fast redirections.
After checking different permutations, here's a summary of compatibility issues:
< 13.4.0 (giving blank page)
13.4.3 - 13.4.9 (giving 500 on refresh and on duplicate tab showing code window)
13.4.10+ (giving server side error and raised separate issue here)
To summarise we are getting errors with every version.
@AnirudhaGohokar still error exists. If I refresh those pages 500 Internal Server Error.
Hi!
We also have the same issue.
How we can get that behavior:
- Create a Next.js page with revalidation every X minutes
- At
getStaticProps
of your page, do some call to an external resource that can be unavailable (high traffic, network failure, random crashes) and throw an error.- Next.js fail to generate that page.
- For an unknown reason, Amplify assume that the result is a success-generated page and delivers it to S3/Cloudfront.
After months of investigations, we continue to don't understand why AWS Amplify works that way.
We only could "workaround" that issue by making the page return some content (text/string) instead of just
throwing
the error to Next.js. But it is still useless.Seems to us that Amplify makes 2 different tries to generate that page: one using the correct SSR and trying to generate a full static page. Other rendering the page/components with default values and relying on Next.js to do the hydration at the client-side with results of
getStaticProps
.
- Is that correct?
- Why Amplify doesn't understand a failed revalidation and just discard the result? Keeping to clients the old and correct content.
Hi. After this error occurs, does page display content again for new requests in the next revalidation cycle, if successful, without manual intervention? If not, how are you handling that?
Hi @andre-mr ,
Yeah, after some revalidation cycles, the page returns without any intervention.
But we never know if it will take 30 minutes, 1 hour, 2 hours or more.
Hi!
We also have the same issue.
How we can get that behavior:
- Create a Next.js page with revalidation every X minutes
- At
getStaticProps
of your page, do some call to an external resource that can be unavailable (high traffic, network failure, random crashes) and throw an error.- Next.js fail to generate that page.
- For an unknown reason, Amplify assume that the result is a success-generated page and delivers it to S3/Cloudfront.
After months of investigations, we continue to don't understand why AWS Amplify works that way.
We only could "workaround" that issue by making the page return some content (text/string) instead of just
throwing
the error to Next.js. But it is still useless.Seems to us that Amplify makes 2 different tries to generate that page: one using the correct SSR and trying to generate a full static page. Other rendering the page/components with default values and relying on Next.js to do the hydration at the client-side with results of
getStaticProps
.
- Is that correct?
- Why Amplify doesn't understand a failed revalidation and just discard the result? Keeping to clients the old and correct content.
@CauanCabral we are experiencing a similar issue as the one stated in this thread. As we still don't have a solution my focus was caught by the fact you were able to do a "workaround". Even if it's just a body content change can you please advise on how you were able to catch the blank page from the code and manipulate the content?