Open zenzen-sol opened 3 months ago
@zenzen-sol This is likely because the headers size was limited, so next/font
was taking precedence.
We expanded these headers →
I am taking a look to confirm!
@zenzen-sol
Despite the headers size increase, I only see the next-intl
's link headers, which probably makes sense (React calculates what is the best items to add to the link headers).
@samcx I can confirm that I'm seeing the same when deploying to Vercel. At this point, I'll assume that the correct header will be set, although I haven't found any way to confirm it locally. (Still seeing only the font optimization headers when running in dev.)
Thanks for looking into this!
@zenzen-sol I am also seeing that on next dev
.
I think what is probably happening is these i18n
headers are working differently in next build
. (locally using next build
, it shows).
It's tough to say why it gets flipped and explain why next/font
doesn't show on next build
, but I do know React is making these decisions to best organize what to preload first.
In the meantime, I will be closing this issue!
Hey @samcx, I hope it's ok for me to chime in.
I've tested with the latest canary and am observing the same behavior as you do: In development, only the React optimization header value for Link
shows up and after a production build, only a manually set value for Link
is returned (in this case set by next-intl
).
There are two aspects here that worry me a bit:
reactMaxHeadersLength
to a value like 999999999
, the behavior is exactly the same. Could it be, that a logic for merging headers is missing here? That's at least what I'd hope to exist and I guess there's a need for both: proper i18n links as well as performance optimization.Link
response header being overridden in development is quite unfortunate. While I'm happy that it still exists in production, I'd assume this to be rather confusion for developers who want to verify the header is there. Note that the Link
response header in the i18n use case is not an optimization, but a necessary signal to search engines to link together multilingual pages. The absence of this header could result in search engines recognizing variants of pages as duplicates and de-indexing them. Therefore this is quite a crucial functionality.Any chance we could get to the bottom of this and see if there's something to be adjusted in Next.js to work correctly?
@amannn Thank you for the clarification! I should have also checked next-intl
when next/font
wasn't present. When next/font
isn't present, the next-intl
Link Headers do show up in next dev
.
Not sure if it's getting "replaced," but I have shared this with our team!
Awesome, thanks a lot @samcx!
@samcx I've just tried out Next.js 15 RC 2 and this issue is still present. Are you working on a fix? I also noticed this affects next/image
if priority
is used.
I've simplified the reproduction further:
link
header from the middleware.
next/font
is used, alternate links from the middleware disappear (both in dev and prod).
next/image
with priority
is used, again the alternate links from the middleware disappear. Note however, that they compose with the ones from next/font
.
The expected behavior would be that the link
header that is set in the middleware should always be preserved.
Note that the link
header can be of critical importance for sites that use this mechanism to instruct search engines about pages being available in multiple languages. If the header is missing, it can result in search engines interpreting the variants as duplicate content.
In Next.js 14 this works fine, please ensure a smooth upgrade path for users who rely on this mechanism 🙏 (i.e. most of the people using next-intl
).
@samcx Unfortunately, this is still the case in the stable release of Next.js 15. Are there plans to fix this? As mentioned in my previous comment, this header is critical for search engines to link content correctly, avoiding marking content as duplicate.
@amannn There are still plans to fix this, we just did not get to this issue yet!
We will get back to you when we have an update on this.
Got it, thanks!
Mmmm really this issue is critical, I am being forced to avoid Next/Font until this issue is resolved, could be useful to check this action https://github.com/vercel/next.js/actions/runs/11649654749/job/32437409528?pr=71925 to see if the PR works, the PR seems right
There is no way to avoid this issue loading all by myself
Hey I have been looking for a solution for it, this component can be loaded in the Layout and made the same function as the Link Header
const headersStore = await headers();
const host = headersStore.get("host") as string;
const params = await props.params;
const { locale } = params;
// ...
return (
...
<Alternates host={host} locale={locale} />
...
)
"use client";
import { routing, usePathname } from "@/i18n/routing";
import { notFound } from "next/navigation";
type Locale = (typeof routing)["locales"][number];
type Props = {
host: string;
locale: Locale;
};
export default function Alternates({ host, locale }: Props) {
const pathname = usePathname();
if (!routing.locales.includes(locale as Locale)) {
notFound();
}
const path = pathname === "/" ? "" : pathname;
return (
<>
{routing.locales.map((l) => {
return (
<link
key={l}
rel="alternate"
hrefLang={l}
href={`https://${host}/${l}${path}`}
/>
);
})}
<link
rel="alternate"
hrefLang="x-default"
href={`https://${host}${path}`}
/>
</>
);
}
Link to the code that reproduces this issue
https://github.com/zenzen-sol/next-reproduction-template/tree/sol/repro-001-next-15-broken
To Reproduce
pnpm i && pnpm run dev
http://localhost:3000
in a browser.Examples:
next/font
(NextJS 15.0.0-rc.0): https://github.com/zenzen-sol/next-reproduction-template/tree/sol/repro-001-next-15-workingCurrent vs. Expected behavior
The
next-intl
library's middleware injects "alternate" links into the response header for SEO purposes. At the same time,next/font
injects "preload" header links into the response header. Both sets of links should appear in the response header. This was working correctly in Next 14.Since NextJS 14.3.0-canary.43 and 15.0.0-canary.0, the "alternate" links from
next-intl
are no longer present whennext/font
is used.Provide environment information
Which area(s) are affected? (Select all that apply)
Font (next/font), Internationalization (i18n), Metadata, Middleware
Which stage(s) are affected? (Select all that apply)
next dev (local), Vercel (Deployed)
Additional context
I tested my reproduction against canary releases back to
14.3.0-canary.0
. This issue first appears in v14.3.0-canary.43, and is not present in14.3.0-canary.42
.If I had to guess, the issue is related to the changes made to
packages/next/src/server/app-render/app-render.tsx
in that prerelease.