Skip to content

Suspense and streaming not working in NextJS on CloudFront

0

I am developing a web app with nextjs and open-next / sst on cloudfront. I have a simple server rendered page with a server component that should refetch data on every query change, wrapped in a Suspense to show the loading fallback as the data is fetched.

The problem is that my suspense fallback is never shown, even though the fetch takes place and the data is updated. Instead, the UI is blocked until the data comes back from the api endpoint. To confirm this was related to cloudfront I deployed the app via vercel and the suspense works as expected. My best guess was adding the X-Accel-Buffering header but cloudfront doesn't allow it. Is there any way to enable this streaming / suspense loading and make it work as it should?

This is the minimal reproduction code: https://github.com/Dragosp33/suspense-nextjs

And here are the two deployments:

2 Answers
1

The issue you're experiencing with Suspense and streaming not working in NextJS on CloudFront is likely related to how CloudFront handles streaming responses. By default, CloudFront may buffer responses before sending them to the client, which can interfere with the streaming behavior expected by NextJS for Suspense to work properly.

To enable streaming and make Suspense work as intended with CloudFront, you can try the following approaches:

  1. Disable caching: If your use case allows, you can disable caching for the relevant paths in your CloudFront distribution. This can be done by using the managed cache policy "CachingDisabled" for the specific behavior that serves your NextJS app. This will prevent CloudFront from buffering the response.

  2. Configure minimum TTL: Set the minimum TTL for the cache behavior to 0 and configure your origin (in this case, your NextJS server) to send appropriate Cache-Control headers. You can set headers like "Cache-Control: no-store" or "Cache-Control: no-cache" to prevent caching and encourage streaming behavior.

  3. Use Lambda@Edge: You can create a Lambda@Edge function that modifies the response headers to include "Transfer-Encoding: chunked". This can help signal to CloudFront that the response should be streamed rather than buffered.

  4. Optimize origin response timeout: Ensure that the origin response timeout in your CloudFront distribution is set appropriately. A longer timeout might be necessary to allow for streaming responses, especially if your data fetching takes some time.

  5. Check SST/OpenNext configuration: Review your SST or OpenNext configuration to ensure it's not introducing any buffering or caching that could interfere with streaming. Make sure you're using the latest versions of these tools, as they may have improvements for handling streaming responses.

If these approaches don't resolve the issue, you may need to consider alternative deployment methods that better support NextJS streaming and Suspense, such as using AWS Application Load Balancer or API Gateway instead of CloudFront directly.

Remember that streaming support in CloudFront can be complex, and the exact solution may depend on your specific setup and requirements. You might need to experiment with different combinations of these approaches to find the one that works best for your application.
Sources
Request and response behavior for custom origins - Amazon CloudFront
Request and response behavior for Amazon S3 origins - Amazon CloudFront

answered a year ago

EXPERT

reviewed a year ago

0
Accepted Answer

This seems to be a problem with open-next configuration. A simple overriding of the lambda-streaming seems to get the job done.

open-next.config.ts:

const config = {
  default: {
    override: {
      wrapper: 'aws-lambda-streaming',
    },
  },
};

export default config;

Reference: https://sst.dev/docs/examples/#aws-nextjs-streaming

answered a year ago

EXPERT

reviewed a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.