Replies: 2 comments 2 replies
-
|
Thanks for the snippets, I'm sure other developers will find them helpful! As you've shown above, it really doesn't take that much code in userland to do this and people might still want to customize based on their needs. For the time being, I think exporting |
Beta Was this translation helpful? Give feedback.
-
|
I created a custom utility that maps each locale to its correct domain. export function getDomain({ locale }: { locale: Locale }) {
return routing.domains?.find((d) =>
(d.locales as unknown as Locale[])?.includes(locale)
)?.domain;
}The sitemap reads the current domain and protocol from the request headers. import type { MetadataRoute } from "next";
import { headers } from "next/headers";
import { getDomain, getPathname } from "@/i18n/navigation";
import { routing } from "@/i18n/routing";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const domain = (await headers()).get("host");
const protocol = (await headers()).get("x-forwarded-proto");
const locale =
routing.domains?.find((d) => d.domain === domain)?.defaultLocale ??
routing.defaultLocale;
return [
{
url: `${protocol}://${getDomain({ locale })}${getPathname({ locale, href: "/" })}`,
lastModified: new Date(),
alternates: {
languages: Object.fromEntries(
routing.locales.map((loc) => [
loc,
protocol +
`://${getDomain({ locale: loc })}${getPathname({ locale: loc, href: "/" })}`,
])
),
},
},
];
}The same domain-resolver function is used for metadata tags, ensuring consistent SEO output for: export async function generateMetadata({
params,
}: PageProps<"/[locale]">): Promise<Metadata> {
const { locale } = (await params) as { locale: Locale };
const protocol = (await headers()).get("x-forwarded-proto");
const t = await getExtracted("Metadata");
return {
title: t("Home Page"),
description: t("Welcome to our localized home page!"),
alternates: {
canonical: `${protocol}://${getDomain({ locale })}${getPathname({ locale, href: "/" })}`,
languages: Object.fromEntries(
routing.locales.map((loc) => [
loc,
`${protocol}://${getDomain({ locale: loc })}${getPathname({ locale: loc, href: "/" })}`,
])
),
},
openGraph: {
url: `${protocol}://${getDomain({ locale })}${getPathname({ locale, href: "/" })}`,
locale,
alternateLocale: routing.locales.filter((loc) => loc !== locale),
},
};
}so is there any better method to make sitemap return like this <?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>http://us.my-app.test</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://us.my-app.test" />
<xhtml:link rel="alternate" hreflang="fr-FR" href="http://fr.my-app.test" />
<xhtml:link rel="alternate" hreflang="fr-CA" href="http://ca.my-app.test" />
<xhtml:link rel="alternate" hreflang="en-CA" href="http://ca.my-app.test/en" />
</url>
...
</urlset>and for metadata return like this <head>
...
<link rel="canonical" href="http://us.my-app.test">
<link rel="alternate" hreflang="en-US" href="http://us.my-app.test">
<link rel="alternate" hreflang="fr-FR" href="http://fr.my-app.test">
<link rel="alternate" hreflang="fr-CA" href="http://ca.my-app.test">
<link rel="alternate" hreflang="en-CA" href="http://ca.my-app.test/en">
...
</head> |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I propose adding a built-in getAlternates helper to next-intl for generating localized alternate URLs with optional locale exclusion. This is a common pattern for building sitemaps, metadata alternates.languages, and SEO-friendly routing.
Suggested Implementation (Minimal)
and we cant extract it from createNavigation API
Use Cases:
1. Generating Localized Sitemaps
2. Metadata Alternates (alternates.languages)
3. Showing Links to Translated Blog Posts
Beta Was this translation helpful? Give feedback.
All reactions