- Create new API route /api/rybbit/track to proxy Rybbit tracking requests - Extract real client IP from Cloudflare headers (cf-connecting-ip) - Forward X-Forwarded-For and X-Real-IP headers to analytics backends - Update OpenPanel proxy to also forward client IP - Update next.config.ts rewrite to use internal API route This fixes geo-location issues where all traffic appeared to come from Cloudflare edge locations instead of actual visitor countries.
64 lines
1.8 KiB
TypeScript
64 lines
1.8 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 AnalyticsProvider from "@/components/providers/AnalyticsProvider";
|
|
|
|
const RYBBIT_SITE_ID = process.env.NEXT_PUBLIC_RYBBIT_SITE_ID || "1";
|
|
|
|
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 = validLocale === DEFAULT_LOCALE ? "" : `/${validLocale}`;
|
|
|
|
const languages: Record<string, string> = {};
|
|
for (const loc of SUPPORTED_LOCALES) {
|
|
const prefix = loc === DEFAULT_LOCALE ? "" : `/${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 (
|
|
<>
|
|
<AnalyticsProvider clientId={process.env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID || ""} />
|
|
<Script
|
|
src="/api/script.js"
|
|
data-site-id={RYBBIT_SITE_ID}
|
|
strategy="afterInteractive"
|
|
/>
|
|
<NextIntlClientProvider messages={messages}>
|
|
{children}
|
|
</NextIntlClientProvider>
|
|
</>
|
|
);
|
|
}
|