57bae7ed6f
Fixed Canonical Redirect Error in Google Search Console by ensuring canonical URLs always include the locale prefix (/sr, /en, /de, /fr) instead of omitting it for the default locale. Changes: - layout.tsx: Fixed canonical and hreflang URL generation - page.tsx: Fixed homepage canonical URL - contact/page.tsx: Fixed contact page canonical URL - about/page.tsx: Fixed about page canonical URL - products/page.tsx: Fixed products page canonical URL - products/[slug]/page.tsx: Fixed product detail canonical URL Before: /contact (when locale=sr) After: /sr/contact (all locales) Fixes: Canonical Redirect Error in Google Search Console
78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import { Metadata } from "next";
|
|
import { NextIntlClientProvider } from "next-intl";
|
|
import { getMessages, setRequestLocale } from "next-intl/server";
|
|
import { SUPPORTED_LOCALES, DEFAULT_LOCALE, isValidLocale } from "@/lib/i18n/locales";
|
|
import Script from "next/script";
|
|
import ExitIntentDetector from "@/components/home/ExitIntentDetector";
|
|
|
|
const RYBBIT_SITE_ID = process.env.NEXT_PUBLIC_RYBBIT_SITE_ID || "1";
|
|
const RYBBIT_HOST = process.env.NEXT_PUBLIC_RYBBIT_HOST || "https://rybbit.nodecrew.me";
|
|
|
|
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://manoonoils.com";
|
|
|
|
export function generateStaticParams() {
|
|
return SUPPORTED_LOCALES.map((locale) => ({ locale }));
|
|
}
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: {
|
|
params: Promise<{ locale: string }>;
|
|
}): Promise<Metadata> {
|
|
const { locale } = await params;
|
|
const validLocale = isValidLocale(locale) ? locale : DEFAULT_LOCALE;
|
|
const localePrefix = `/${locale}`;
|
|
|
|
const languages: Record<string, string> = {};
|
|
for (const loc of SUPPORTED_LOCALES) {
|
|
const prefix = `/${loc}`;
|
|
languages[loc] = `${baseUrl}${prefix}`;
|
|
}
|
|
|
|
return {
|
|
alternates: {
|
|
canonical: `${baseUrl}${localePrefix}`,
|
|
languages,
|
|
},
|
|
};
|
|
}
|
|
|
|
export default async function LocaleLayout({
|
|
children,
|
|
params,
|
|
}: {
|
|
children: React.ReactNode;
|
|
params: Promise<{ locale: string }>;
|
|
}) {
|
|
const { locale } = await params;
|
|
setRequestLocale(locale);
|
|
const messages = await getMessages();
|
|
|
|
return (
|
|
<>
|
|
<Script
|
|
id="mautic-tracking"
|
|
strategy="afterInteractive"
|
|
dangerouslySetInnerHTML={{
|
|
__html: `
|
|
(function(w,d,t,u,n,a,m){w['MauticTrackingObject']=n;
|
|
w[n]=w[n]||function(){(w[n].q=w[n].q||[]).push(arguments)},a=d.createElement(t),
|
|
m=d.getElementsByTagName(t)[0];a.async=1;a.src=u;m.parentNode.insertBefore(a,m)
|
|
})(window,document,'script','https://mautic.nodecrew.me/mtc.js','mt');
|
|
mt('send', 'pageview');
|
|
`,
|
|
}}
|
|
/>
|
|
<Script
|
|
src={`${RYBBIT_HOST}/api/script.js`}
|
|
data-site-id={RYBBIT_SITE_ID}
|
|
strategy="afterInteractive"
|
|
/>
|
|
<NextIntlClientProvider messages={messages}>
|
|
{children}
|
|
<ExitIntentDetector />
|
|
</NextIntlClientProvider>
|
|
</>
|
|
);
|
|
}
|