Repository navigation
Setting Http headers like Cache-Tags inside App Routes #95058
Replies: 6 comments 3 replies
|
You must be using App Router though, no? This is not a limitation of Next.js, necessarily, but streaming, headers are already sent. In Pages Router, you can do this in What is the usage at the of the day, caching in a CDN? Feels like yeah, you'd need to have a fast path in the proxy/middleware to get the data you need, preferably with a key-value store in front, to lower latency. |
|
Your instinct is right that you can't set the header from How you solve it depends on what the If you want Next's own cache to be tag-invalidatable, skip the header entirely. Tag the fetch and let Next track it: const res = await fetch(`https://api.example.com/page/${slug}`, {
next: { tags: [`article_${articleId}`] },
})Then invalidate with If you specifically need the // middleware.ts
const data = await fetch(apiUrl).then(r => r.json())
const res = NextResponse.rewrite(req.nextUrl, {
request: { headers: new Headers({ 'x-article-id': String(data.article_id) }) },
})
res.headers.set('Cache-Tag', `article_${data.article_id}`)
return resNow One thing that won't work: If it's the second case, the middleware-passes-data-down pattern is the standard way people handle surrogate keys on Next today. |
|
Hi Alec, Since Next.js Server Components ( The absolute best and cleanest workaround to handle this—without duplicating your API fetch calls in a middleware—is to use a Route Handler (API Route) as a data proxy. Solution: Route Handler ProxyMove your external API call into a custom Route Handler (e.g., // app/api/content/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const slug = searchParams.get('slug');
const location = searchParams.get('location');
// 1. Fetch data from your external API backend
const res = await fetch(`[https://api.yourbackend.com/content?slug=$](https://api.yourbackend.com/content?slug=$){slug}&location=${location}`);
const data = await res.json();
// 2. Create the response object
const response = NextResponse.json(data);
// 3. Cleanly inject your dynamic article ID into the HTTP Cache-Tag header
if (data?.article_id) {
response.headers.set('Cache-Tag', `article_${data.article_id}`);
}
return response;
}
// app/[slug]/page.tsx
export default async function Page({ params, searchParams }) {
const slug = params.slug;
const location = searchParams.location;
// Fetching from your Route Handler proxy maintains a single network request to your backend
const res = await fetch(`[https://yourdomain.com/api/content?slug=$](https://yourdomain.com/api/content?slug=$){slug}&location=${location}`);
const data = await res.json();
return (
<div>
{/* Render your page content here */}
</div>
);
} |
|
Because React Server Components in Next.js stream HTML to the client as chunks resolve, HTTP response headers must be sent before body streaming begins. That is why Next.js does not allow mutating outgoing response headers directly from within Depending on whether your 1. If you are trying to tag the cache for Next.js Revalidation (
|
|
You can't set response headers from a page component, that part's correct — Next doesn't expose that. But honestly I'd stop fighting the raw header and use Next's own tag system instead: tag the fetch itself with |
|
Thanks for bringing this up in Setting Http headers like Cache-Tags inside App Routes. I am following this discussion and looking into the details. Happy to help test or contribute to this area! |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Summary
Hi,
We are using App routes in our Next.js project v14. Our
page.tsxfile, calls an API endpoint with the page slug and user location as parameters to retrieve the page content. Our use case is to pick the property article_id from the API Endpoint response and set it in the HTTP Cache-Tag headere.g. Cache-Tag: article_10.
At the moment its not possible to set Http headers inside the
page.tsxfile due to limitation of next.js. We have thought about adding the API call as a middleware, however it's not in the page context in middleware or we would have to duplicate calls to the Api endpoint once in middleware and once in page.tsx.Is there a workaround that we could use at to set http headers inside the App routes (page.tsx)
Thanks in advance for you help.
Alec
Additional information
No response
Example
No response
All reactions