diff --git a/next-sitemap.config.js b/next-sitemap.config.js index 5e5ee4e0caa..daeba00e0d0 100644 --- a/next-sitemap.config.js +++ b/next-sitemap.config.js @@ -1,6 +1,8 @@ const i18nConfig = require("./i18n.config.json") const locales = i18nConfig.map(({ code }) => code) +const defaultLocale = "en" + /** @type {import('next-sitemap').IConfig} */ module.exports = { siteUrl: process.env.SITE_URL || "https://ethereum.org", @@ -8,9 +10,21 @@ module.exports = { transform: async (_, path) => { const rootPath = path.split("/")[1] if (path.endsWith("/404")) return null - const isDefaultLocale = !locales.includes(rootPath) || rootPath === "en" + const isDefaultLocale = + !locales.includes(rootPath) || rootPath === defaultLocale + + // Strip default-locale (en) prefix from paths; drop the `/en` root entry + let loc = path + if (rootPath === defaultLocale) { + // Drop the `/en` root entry to avoid duplicating `/` + if (path === `/${defaultLocale}` || path === `/${defaultLocale}/`) + return null + const defaultLocalePrefix = new RegExp(`^/${defaultLocale}(/|$)`) + loc = path.replace(defaultLocalePrefix, "/") + } + return { - loc: path, + loc, changefreq: isDefaultLocale ? "weekly" : "monthly", priority: isDefaultLocale ? 0.7 : 0.5, } diff --git a/src/components/Matomo.tsx b/src/components/Matomo.tsx index 5ef774d0ff4..d5f3bcf638b 100644 --- a/src/components/Matomo.tsx +++ b/src/components/Matomo.tsx @@ -5,6 +5,7 @@ import { usePathname } from "next/navigation" import { init, push } from "@socialgouv/matomo-next" import { IS_PREVIEW_DEPLOY } from "@/lib/utils/env" +import { normalizePathForMatomo } from "@/lib/utils/matomo" export default function Matomo() { const pathname = usePathname() @@ -40,8 +41,11 @@ export default function Matomo() { return setPreviousPath(pathname) } - push(["setReferrerUrl", `${previousPath}`]) - push(["setCustomUrl", pathname]) + const normalizedPreviousPath = normalizePathForMatomo(previousPath) + const normalizedPathname = normalizePathForMatomo(pathname) + + push(["setReferrerUrl", normalizedPreviousPath]) + push(["setCustomUrl", normalizedPathname]) push(["deleteCustomVariables", "page"]) setPreviousPath(pathname) // In order to ensure that the page title had been updated, diff --git a/src/i18n/routing.ts b/src/i18n/routing.ts index a9d4c20c9ab..5dc74ed8e33 100644 --- a/src/i18n/routing.ts +++ b/src/i18n/routing.ts @@ -7,6 +7,7 @@ export const routing = defineRouting({ locales: LOCALES_CODES, defaultLocale: DEFAULT_LOCALE, localeCookie: false, + localePrefix: "as-needed", }) // Lightweight wrappers around Next.js' navigation APIs diff --git a/src/lib/utils/matomo.ts b/src/lib/utils/matomo.ts index f64952b1a2a..297211e46b8 100644 --- a/src/lib/utils/matomo.ts +++ b/src/lib/utils/matomo.ts @@ -1,9 +1,29 @@ import { push } from "@socialgouv/matomo-next" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + import { IS_PROD } from "./env" export const MATOMO_LS_KEY = "ethereum-org.matomo-opt-out" +/** + * Normalizes paths to ensure consistent Matomo tracking. + * With localePrefix: "as-needed", English paths don't have /en prefix, + * but we want to track them as /en paths for analytics consistency. + */ +export const normalizePathForMatomo = (pathname: string): string => { + const hasLocalePrefix = LOCALES_CODES.some((locale) => + pathname.startsWith(`/${locale}/`) + ) + + if (hasLocalePrefix) { + return pathname + } + + // For paths without locale prefix (English content), add /en prefix + return `/${DEFAULT_LOCALE}${pathname}` +} + export interface MatomoEventOptions { eventCategory: string eventAction: string @@ -27,6 +47,10 @@ export const trackCustomEvent = ({ if (isOptedOut) return // Set custom URL removing any query params or hash fragments - window && push([`setCustomUrl`, window.location.href.replace(/[?#].*$/, "")]) + if (window) { + const normalizedPathname = normalizePathForMatomo(window.location.pathname) + const normalizedUrl = window.location.origin + normalizedPathname + push([`setCustomUrl`, normalizedUrl]) + } push([`trackEvent`, eventCategory, eventAction, eventName, eventValue]) } diff --git a/src/lib/utils/url.ts b/src/lib/utils/url.ts index a35e9f759de..8c6cf4616b1 100644 --- a/src/lib/utils/url.ts +++ b/src/lib/utils/url.ts @@ -50,7 +50,9 @@ export const addSlashes = (href: string): string => { } export const getFullUrl = (locale: string | undefined, path: string) => - addSlashes(new URL(join(locale || DEFAULT_LOCALE, path), SITE_URL).href) + DEFAULT_LOCALE === locale || !locale + ? addSlashes(new URL(path, SITE_URL).href) + : addSlashes(new URL(join(locale, path), SITE_URL).href) // Remove trailing slash from slug and add leading slash export const normalizeSlug = (slug: string) => {