Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR output includes “/en” prefix for default locale despite localePrefix: "as-needed" #1635

Open
3 tasks done
iProgrammerDmytro opened this issue Dec 27, 2024 · 0 comments
Labels
bug Something isn't working unconfirmed Needs triage.

Comments

@iProgrammerDmytro
Copy link

Description

We’re using Next-Intl in our Next.js 14.2.13 project to support multiple locales. Our default locale is English (en), and in routing.ts we set:

export const routing = defineRouting({
  locales: ["en", "es", "de", "fr", "nl"],
  defaultLocale: "en",
  localePrefix: "as-needed",
  // ... pathnames
});

Expected behavior:

• The default locale (en) should not show the "/en" prefix in server‐rendered HTML (SSR).
• When browsing in the browser’s DevTools Elements tab, we indeed see links like href="/book-a-demo" for English.

Actual behavior:
• In “View Page Source” (or if we do curl https://www.example.com), the SSR HTML has href="/en/book-a-demo" for English pages.
• This means search engine crawlers (Ahrefs, etc.) detect "/en/..." and flag them as redirects.
• After hydration on the client, the final DOM changes them to "/book-a-demo", but the raw SSR output still has "/en/".

We’ve verified there are no explicit references to "/en/" in our code (we searched the repo). Our localePrefix: "as-needed" is supposed to hide the default-locale prefix. However, SSR is still injecting "/en/".

Verifications

Mandatory reproduction URL

Unfortunately, we don’t currently have a public minimal repo reproducing this. But here are some relevant code snippets from our real project. We can try to create a smaller reproduction if needed

Reproduction description

  1. Install Next.js ^14.2.13 and Next-Intl ^3.19.4.
  2. Configure routing.ts:
import { defineRouting } from "next-intl/routing";
import { createLocalizedPathnamesNavigation } from "next-intl/navigation";

export const routing = defineRouting({
  locales: ["en", "es", "de", "fr", "nl"],
  defaultLocale: "en",
  localePrefix: "as-needed",
  pathnames: {
    "/": "/",
    "/book-a-demo": {
      en: "/book-a-demo",
      es: "/reservar-una-demostracion",
      // ...
    },
    // etc.
  },
});

export const { Link, usePathname, useRouter } =
  createLocalizedPathnamesNavigation(routing);
  1. Use Next-Intl’s middleware in middleware.ts:
import createMiddleware from "next-intl/middleware";
import { routing } from "./i18n/routing";

export default createMiddleware(routing, {
  localeDetection: false,
  alternateLinks: false,
});

export const config = {
  matcher: ["/((?!api|static|.*\\..*|_next).*)"],
};
  1. SSR output (via “View Page Source” or curl):

<a href="/en/book-a-demo" class="...">Discover our Global Benefits</a>

That’s not what we expect for the default English locale.

  1. Client (via DevTools Elements tab) eventually shows:

<a href="/book-a-demo" class="...">Discover our Global Benefits</a>

which is correct.

Expected Behaviour

• The server‐rendered HTML should show href="/book-a-demo" for the default locale, matching localePrefix: "as-needed".

Additional Details / Screenshots

• Our next.config.mjs:

import createNextIntlPlugin from "next-intl/plugin";
import { withSentryConfig } from "@sentry/nextjs";

const withNextIntl = createNextIntlPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {
  trailingSlash: false,
  // no built-in i18n config
  images: {...},
  rewrites: async () => [...],
  async redirects() {
    // ...
  },
};

export default withSentryConfig(withNextIntl(nextConfig), {...}, {...});

• We do not have a built-in Next.js i18n block in next.config.mjs.
• Screenshot of “View Page Source” with /en/book-a-demo (attached).

Screenshot 2024-12-27 at 13 25 02

• Screenshot of “Elements tab” showing "/book-a-demo" (attached).

Screenshot 2024-12-27 at 13 22 12

Expected behaviour

We believe localePrefix: "as-needed" should prevent "/en/" from appearing at SSR for the default locale. Yet the SSR HTML still includes "/en", while the client re-hydrates to the correct "/". Any guidance on how to ensure the SSR output fully omits "/en/" for English would be very appreciated!

Thank you for your time!

@iProgrammerDmytro iProgrammerDmytro added bug Something isn't working unconfirmed Needs triage. labels Dec 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working unconfirmed Needs triage.
Projects
None yet
Development

No branches or pull requests

1 participant