Skip to content

Unable to dynamically set response headers in page.js components (App router) #50914

@leonbe02

Description

@leonbe02

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Latest next.js app

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true)

Link to the code that reproduces this issue or a replay of the bug

n/a

To Reproduce

Create an app/page.js file and then cry when you realize there is no way to set a response header based on data you fetched to render the page.

Describe the Bug

When using the Page router, you are able to dynamically set response headers within the getServerSideProps function since it is passed a reference to the response object. When using the App router, there is no method in which you can dynamically set a header on the response based on data fetches that occur when SSR the page. This appears to be a regression or missed feature that wasn't migrated from the Page router.

import getProduct from '@/lib/getProduct.js';

export function getServerSideProps({ res, query }) {
  const product = await getProduct(query.slug);
  if (!product) return { notFound: true };

  let maxAge = 86400;
  if (product.saleEndDate > Date.now()) {
    maxAge = Math.min(
      maxAge,
      Math.floor((product.saleEndDate - Date.now()) / 1000)
    );
  }

  res.setHeader('Surrogate-Key', product.id);
  res.setHeader('Surrogate-Control', `max-age=${maxAge}`);

  return {
    props: { product }
  };
}

Expected Behavior

When using the App router, you can get a read-only copy of the request headers, but I'd expect there to be a method in which I can dynamically set the response header based on data I fetched to render the page server-side.

The main use case for us is to set the Surrogate-Key header which is used by our CDN (Fastly) to programmatically purge the cache via tagging: https://docs.fastly.com/en/guides/working-with-surrogate-keys

The only methods I see for setting response headers currently when using the App router is to apply them in the middleware or in the next.config.js. Both of these options are not aware of the data that was fetched when rendering a page so neither of them are able to set headers using data from the page.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue was opened via the bug report template.locked

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions