Files
manoon-headless/next.config.ts
Unchained d999d739d5
Some checks failed
Build and Deploy / build (push) Has been cancelled
fix(analytics): connect directly to Rybbit to preserve real visitor IP
Changed Rybbit script loading from server-side rewrite to client-side direct
connection. This prevents Next.js from proxying the request, which was causing
all visitor IPs to show as the Hetzner server IP (138.201.11.251).

Before:
- Browser → Next.js → Rybbit (server-side proxy, loses client IP)

After:
- Browser → Rybbit (direct connection, real IP preserved)

Changes:
- layout.tsx: Use direct Rybbit URL for script src
- next.config.ts: Remove /api/script.js rewrite
2026-04-03 20:10:59 +02:00

95 lines
2.5 KiB
TypeScript

import createNextIntlPlugin from "next-intl/plugin";
import type { NextConfig } from "next";
const withNextIntl = createNextIntlPlugin();
const nextConfig: NextConfig = {
output: 'standalone',
async redirects() {
return [
// Fix malformed URLs with /contact appended to product slugs
{
source: '/:locale(en|sr)/products/:slug*/contact',
destination: '/:locale/products/:slug*',
permanent: true,
},
{
source: '/products/:slug*/contact',
destination: '/products/:slug*',
permanent: true,
},
// Redirect old/removed product "manoon" to products listing
{
source: '/:locale(en|sr)/products/manoon',
destination: '/:locale/products',
permanent: true,
},
{
source: '/products/manoon',
destination: '/products',
permanent: true,
},
];
},
async rewrites() {
const rybbitHost = process.env.NEXT_PUBLIC_RYBBIT_HOST || "https://rybbit.nodecrew.me";
return [
// Note: /api/script.js now connects directly to Rybbit (client-side)
// to preserve real visitor IP instead of proxying through Next.js
{
source: "/api/track",
destination: "/api/rybbit/track",
},
{
source: "/api/site/tracking-config/:id",
destination: `${rybbitHost}/api/site/tracking-config/:id`,
},
{
source: "/api/replay.js",
destination: `${rybbitHost}/api/replay.js`,
},
{
source: "/api/session-replay/record/:id",
destination: `${rybbitHost}/api/session-replay/record/:id`,
},
];
},
images: {
formats: ["image/avif", "image/webp"],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
remotePatterns: [
{
protocol: "https",
hostname: "manoonoils.com",
pathname: "/**",
},
{
protocol: "https",
hostname: "minio-api.nodecrew.me",
pathname: "/**",
},
{
protocol: "https",
hostname: "api.manoonoils.com",
pathname: "/**",
},
{
protocol: "https",
hostname: "**.saleor.cloud",
pathname: "/**",
},
{
protocol: "https",
hostname: "images.unsplash.com",
pathname: "/**",
},
],
},
experimental: {
optimizePackageImports: ["lucide-react", "framer-motion", "clsx", "motion"],
},
};
export default withNextIntl(nextConfig);