serverless-nextjs / serverless-next.js

⚡ Deploy your Next.js apps on AWS Lambda@Edge via Serverless Components
MIT License
4.41k stars 449 forks source link

Failing to generate new pages after build(ISR) #2563

Open Karlen92 opened 1 year ago

Karlen92 commented 1 year ago
Mac OS Ventura
Next.JS - 12.3.0
Node.JS version - 16.19.0
sls-next/serverless-component - 3.7.0
Serverless Version
  Framework Core: 3.25.1
  Plugin: 6.2.2
  SDK: 4.3.2

Content of serverless.yml

    component: "./node_modules/@sls-next/serverless-component"
    inputs:
      roleArn: "arn:aws:iam::656114780823:role/nygvfxo-ufm55u8" # has admin permissions

The deployment works fine, I deploy from my machine, without any errors.

I'm trying to enable ISR on my project to be able ti generate pages and my getStaticProps looks like this


const OfferingPage: FC<{ offeringData: { data: Offering } }> = () => {
  const router = useRouter();
  return <main className="site-main hfeed" id="main">
      <div data-elementor-type="wp-page" data-elementor-id="2952" className="elementor elementor-2952">
        <div>The ID is {router?.query?.offering_id}</div>
      </div>
  </main>
};

export const getStaticProps: GetStaticProps = async (context) => {
     // I removed every logic from here for simplicity
  return {
    props: {
      offeringData: {},
    },
    revalidate: 60
  };
};

export const getStaticPaths: GetStaticPaths = async () => {
  const responsePremium = await AxiosApiService.getIds(true); 
  const paths = responsePremium?.data?.map((item: string) => {
    return {
      params: { offering_id: item },
    };
  });
  return {
    paths,
    fallback: true,
  };
};

Actual behavior

I have a url structure like thishttps://d1ut6e5vnq8i6g.cloudfront.net/offering/{:id}/. If the id exists in my getStaticPaths, it works fine. However when id is new, and I assume that's when regeneration should happen. However, in those cases application fails with he following error.

Application error: a client-side exception has occurred (see the browser console for more information). This is the browser console log.

Screenshot 2023-01-22 at 18 05 25

Seems like the issue is the 404 request to get static props, which works fine for all existing ids. https://d1ut6e5vnq8i6g.cloudfront.net/_next/data/99wTahfTVhXTAQeDVyzQ3/offering/991a5af4-57ed-4822-855c-02ce590dbd71.json?offering_id=991a5af4-57ed-4822-855c-02ce590dbd71

*note all application logic is removed form the code for simplicity, so my code is exactly as above.

The Lambda for regeneration is being called as expected, it seems, without error, but the files are not added to S3, and no lambda is called besides regeneration lambda(not sure when they meant to).

Expected behavior

I expect the page to be generated on request and returned which does not happen. Can anyone relate the issue, or might be I'm using wrong configuration?

anabellchan commented 1 year ago

I'm having the same issue.

To prove that ISR is working, a timestamp is shown on the page.

ISR is working on localhost, but once deployed to AWS, it uses the same pre-rendered page even with revalidation.

Next.JS - 12.1.6
Node.JS version - 16.7.0
sls-next/serverless-component - 3.6.0
Serverless Version
  Framework Core: 2.72.2
  Plugin: 5.5.4
  SDK: 4.3.2
  Components: 3.18.2

serverless.yml

ContentPages:
  component: "@sls-next/serverless-component@3.6.0"
  inputs:
    timeout:
      apiLambda: 30
    bucketName: ${env.SERVERLESS_BUCKET_NAME}
    name:
      defaultLambda: ${env.SERVERLESS_LAMBDA_NAME}
    policy: "arn:aws:iam::xxxxx:policy/Serverless-IAM-Policy"
    useServerlessTraceTarget: true
    build: true
    verbose: false

Things I tried on getStaticPaths to get revalidation to work, but failed. Cloudwatch logs did not show any new rendering of pages.

  1. This will return an error on any page Application error: a client-side exception has occurred (see the browser console for more information).
  return {
    paths: [],
    fallback: true,
  };
  1. This will return pre-rendered page, with the same timestamp as build time. No revalidation occurs. It returns an error on non-pre-rendered page Application error: a client-side exception has occurred (see the browser console for more information).
  return {
    paths: [selected list of paths],
    fallback: true,
  };
  1. This will return pre-rendered page, with the same timestamp as build time. No revalidation occurs.
  return {
    paths: [all possible paths],
    fallback: true,
  };
  1. Same as #3
  return {
    paths: [all possible paths],
    fallback: 'dynamic',
  };

getStaticProps

export const getStaticProps = async (context: { params: { handle } }) => {
  const {
    params: { handle },
  } = context;
  const time = displayTriggerTime();
  const { props } = await fetchPage({ handle });
  if (props) {
    return {
      props: { ...props, pageData: JSON.stringify(props?.pageData), time },
      revalidate: 30,
    };
  } else {
    return { notFound: true };
  }
};

Response Header:

Screenshot 2023-06-12 at 6 51 19 PM

Expected Result

  1. I should be able to pre-render a small list of pages at build time, and server render the rest on HTTP request.
  2. All pages should revalidate after the revalidation period goes by.