fix(products): resolve 500 mapping error by bypassing MDXRemote for complex JSX
This commit is contained in:
@@ -12,7 +12,7 @@ import { mapFileSlugToTranslated, mapSlugToFileSlug } from '@/lib/slugs';
|
||||
import { Metadata } from 'next';
|
||||
import { getTranslations, setRequestLocale } from 'next-intl/server';
|
||||
import { getProductOGImageMetadata } from '@/lib/metadata';
|
||||
import { MDXRemote } from 'next-mdx-remote/rsc';
|
||||
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { notFound } from 'next/navigation';
|
||||
@@ -103,70 +103,70 @@ export async function generateMetadata({ params }: ProductPageProps): Promise<Me
|
||||
};
|
||||
}
|
||||
|
||||
const components = {
|
||||
ProductTechnicalData,
|
||||
ProductTabs,
|
||||
p: (props: any) => (
|
||||
<p
|
||||
{...props}
|
||||
className="text-lg md:text-xl text-text-secondary leading-relaxed mb-8 font-medium"
|
||||
/>
|
||||
),
|
||||
h2: (props: any) => (
|
||||
<div className="relative mb-16">
|
||||
<h2
|
||||
{...props}
|
||||
className="text-3xl md:text-4xl font-black text-primary tracking-tighter uppercase mb-6"
|
||||
/>
|
||||
<div className="w-20 h-1.5 bg-accent rounded-full" />
|
||||
</div>
|
||||
),
|
||||
h3: (props: any) => (
|
||||
<h3
|
||||
{...props}
|
||||
className="text-2xl md:text-3xl font-black text-primary mb-10 tracking-tight uppercase"
|
||||
/>
|
||||
),
|
||||
ul: (props: any) => <ul {...props} className="list-none pl-0 mb-10" />,
|
||||
section: (props: any) => <div {...props} className="block" />,
|
||||
li: (props: any) => (
|
||||
<li className="flex items-start gap-4 group mb-4 last:mb-0">
|
||||
<div className="mt-2.5 w-2 h-2 rounded-full bg-accent flex-shrink-0 group-hover:scale-125 transition-transform" />
|
||||
<span
|
||||
{...props}
|
||||
className="text-lg md:text-xl text-text-secondary leading-relaxed font-medium"
|
||||
/>
|
||||
</li>
|
||||
),
|
||||
strong: (props: any) => <strong {...props} className="font-black text-primary" />,
|
||||
table: (props: any) => (
|
||||
<div className="overflow-x-auto my-20 rounded-[32px] border border-neutral-dark/10 shadow-xl bg-white p-1">
|
||||
<table {...props} className="min-w-full divide-y divide-neutral-dark/10" />
|
||||
</div>
|
||||
),
|
||||
th: (props: any) => (
|
||||
<th
|
||||
{...props}
|
||||
className="px-8 py-6 bg-neutral-light/50 text-left text-[10px] font-black uppercase tracking-[0.25em] text-primary/60"
|
||||
/>
|
||||
),
|
||||
td: (props: any) => (
|
||||
<td
|
||||
{...props}
|
||||
className="px-8 py-6 text-text-secondary border-t border-neutral-dark/5 text-lg md:text-xl font-medium"
|
||||
/>
|
||||
),
|
||||
hr: () => <hr className="my-24 border-t-2 border-neutral-dark/5" />,
|
||||
blockquote: (props: any) => (
|
||||
<div className="my-20 p-10 md:p-16 bg-primary-dark rounded-[40px] relative overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-64 h-64 bg-accent/10 rounded-full -translate-y-1/2 translate-x-1/2 blur-3xl group-hover:bg-accent/20 transition-colors duration-700" />
|
||||
<div
|
||||
className="relative z-10 italic text-2xl md:text-3xl text-white/90 leading-relaxed font-black tracking-tight"
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
// const components = {
|
||||
// ProductTechnicalData,
|
||||
// ProductTabs,
|
||||
// p: (props: any) => (
|
||||
// <p
|
||||
// {...props}
|
||||
// className="text-lg md:text-xl text-text-secondary leading-relaxed mb-8 font-medium"
|
||||
// />
|
||||
// ),
|
||||
// h2: (props: any) => (
|
||||
// <div className="relative mb-16">
|
||||
// <h2
|
||||
// {...props}
|
||||
// className="text-3xl md:text-4xl font-black text-primary tracking-tighter uppercase mb-6"
|
||||
// />
|
||||
// <div className="w-20 h-1.5 bg-accent rounded-full" />
|
||||
// </div>
|
||||
// ),
|
||||
// h3: (props: any) => (
|
||||
// <h3
|
||||
// {...props}
|
||||
// className="text-2xl md:text-3xl font-black text-primary mb-10 tracking-tight uppercase"
|
||||
// />
|
||||
// ),
|
||||
// ul: (props: any) => <ul {...props} className="list-none pl-0 mb-10" />,
|
||||
// section: (props: any) => <div {...props} className="block" />,
|
||||
// li: (props: any) => (
|
||||
// <li className="flex items-start gap-4 group mb-4 last:mb-0">
|
||||
// <div className="mt-2.5 w-2 h-2 rounded-full bg-accent flex-shrink-0 group-hover:scale-125 transition-transform" />
|
||||
// <span
|
||||
// {...props}
|
||||
// className="text-lg md:text-xl text-text-secondary leading-relaxed font-medium"
|
||||
// />
|
||||
// </li>
|
||||
// ),
|
||||
// strong: (props: any) => <strong {...props} className="font-black text-primary" />,
|
||||
// table: (props: any) => (
|
||||
// <div className="overflow-x-auto my-20 rounded-[32px] border border-neutral-dark/10 shadow-xl bg-white p-1">
|
||||
// <table {...props} className="min-w-full divide-y divide-neutral-dark/10" />
|
||||
// </div>
|
||||
// ),
|
||||
// th: (props: any) => (
|
||||
// <th
|
||||
// {...props}
|
||||
// className="px-8 py-6 bg-neutral-light/50 text-left text-[10px] font-black uppercase tracking-[0.25em] text-primary/60"
|
||||
// />
|
||||
// ),
|
||||
// td: (props: any) => (
|
||||
// <td
|
||||
// {...props}
|
||||
// className="px-8 py-6 text-text-secondary border-t border-neutral-dark/5 text-lg md:text-xl font-medium"
|
||||
// />
|
||||
// ),
|
||||
// hr: () => <hr className="my-24 border-t-2 border-neutral-dark/5" />,
|
||||
// blockquote: (props: any) => (
|
||||
// <div className="my-20 p-10 md:p-16 bg-primary-dark rounded-[40px] relative overflow-hidden group">
|
||||
// <div className="absolute top-0 right-0 w-64 h-64 bg-accent/10 rounded-full -translate-y-1/2 translate-x-1/2 blur-3xl group-hover:bg-accent/20 transition-colors duration-700" />
|
||||
// <div
|
||||
// className="relative z-10 italic text-2xl md:text-3xl text-white/90 leading-relaxed font-black tracking-tight"
|
||||
// {...props}
|
||||
// />
|
||||
// </div>
|
||||
// ),
|
||||
// };
|
||||
|
||||
export default async function ProductPage({ params }: ProductPageProps) {
|
||||
const { locale, slug } = await params;
|
||||
@@ -307,20 +307,25 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
// Extract technical data for schema
|
||||
// Extract technical data from MDX content (bypass MDXRemote which crashes on complex JSX-in-MDX)
|
||||
const technicalDataMatch = product.content.match(
|
||||
/technicalData=\{<ProductTechnicalData data=\{(.*?)\}\s*\/>\}/s,
|
||||
);
|
||||
let technicalItems = [];
|
||||
let technicalData: any = null;
|
||||
let technicalItems: any[] = [];
|
||||
if (technicalDataMatch) {
|
||||
try {
|
||||
const data = JSON.parse(technicalDataMatch[1]);
|
||||
technicalItems = data.technicalItems || [];
|
||||
technicalData = JSON.parse(technicalDataMatch[1]);
|
||||
technicalItems = technicalData.technicalItems || [];
|
||||
} catch (e) {
|
||||
console.error('Failed to parse technical data for schema', e);
|
||||
console.error('Failed to parse technical data', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract section HTML content
|
||||
const sectionMatch = product.content.match(/<section>([\s\S]*?)<\/section>/);
|
||||
const sectionHtml = sectionMatch ? sectionMatch[1] : '';
|
||||
|
||||
const datasheetPath = getDatasheetPath(productSlug, locale);
|
||||
const isFallback = (product.frontmatter as any).isFallback;
|
||||
const categorySlug = slug[0];
|
||||
@@ -340,22 +345,6 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
||||
/>
|
||||
);
|
||||
|
||||
const productComponents = {
|
||||
...components,
|
||||
ProductTabs: (props: any) => <ProductTabs {...props} sidebar={sidebar} />,
|
||||
};
|
||||
|
||||
// Pre-process content to convert raw HTML tags to Markdown so they use our custom components
|
||||
const processedContent = product.content
|
||||
.replace(/<h2[^>]*>(.*?)<\/h2>/g, '\n## $1\n')
|
||||
.replace(/<h3[^>]*>(.*?)<\/h3>/g, '\n### $1\n')
|
||||
.replace(/<p[^>]*>(.*?)<\/p>/g, '\n$1\n')
|
||||
.replace(/<ul[^>]*>(.*?)<\/ul>/gs, '\n$1\n')
|
||||
.replace(/<li[^>]*>(.*?)<\/li>/g, '\n- $1\n')
|
||||
.replace(/<strong[^>]*>(.*?)<\/strong>/g, '**$1**')
|
||||
.replace(/<section[^>]*>/g, '')
|
||||
.replace(/<\/section>/g, '');
|
||||
|
||||
return (
|
||||
<div className="flex flex-col min-h-screen bg-white relative">
|
||||
{/* Product Hero */}
|
||||
@@ -465,9 +454,25 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
||||
|
||||
<div className="relative">
|
||||
<div className="w-full">
|
||||
{/* Main Content Area */}
|
||||
{/* Main Content Area - Direct rendering (bypasses MDXRemote crash) */}
|
||||
<div className="max-w-none">
|
||||
<MDXRemote source={processedContent} components={productComponents} />
|
||||
<ProductTabs
|
||||
technicalData={
|
||||
technicalData ? <ProductTechnicalData data={technicalData} /> : null
|
||||
}
|
||||
sidebar={sidebar}
|
||||
>
|
||||
{sectionHtml && (
|
||||
<div
|
||||
className="prose prose-lg max-w-none
|
||||
[&_h2]:text-3xl [&_h2]:md:text-4xl [&_h2]:font-black [&_h2]:text-primary [&_h2]:tracking-tighter [&_h2]:uppercase [&_h2]:mb-6
|
||||
[&_h3]:text-2xl [&_h3]:md:text-3xl [&_h3]:font-black [&_h3]:text-primary [&_h3]:mb-10 [&_h3]:tracking-tight [&_h3]:uppercase
|
||||
[&_p]:text-lg [&_p]:md:text-xl [&_p]:text-text-secondary [&_p]:leading-relaxed [&_p]:mb-8 [&_p]:font-medium
|
||||
[&_strong]:font-black [&_strong]:text-primary"
|
||||
dangerouslySetInnerHTML={{ __html: sectionHtml }}
|
||||
/>
|
||||
)}
|
||||
</ProductTabs>
|
||||
</div>
|
||||
|
||||
{/* Datasheet Download Section - Only for Medium Voltage for now */}
|
||||
|
||||
@@ -45,7 +45,11 @@ export default function middleware(request: NextRequest) {
|
||||
const hostHeader =
|
||||
headers.get('x-forwarded-host') || headers.get('host') || 'testing.klz-cables.com';
|
||||
|
||||
const [publicHostname] = hostHeader.split(':');
|
||||
|
||||
urlObj.protocol = proto;
|
||||
urlObj.hostname = publicHostname;
|
||||
urlObj.port = ''; // Explicitly clear internal port (3000)
|
||||
|
||||
effectiveRequest = new NextRequest(urlObj, {
|
||||
headers: request.headers,
|
||||
@@ -95,8 +99,7 @@ export default function middleware(request: NextRequest) {
|
||||
|
||||
export const config = {
|
||||
matcher: [
|
||||
'/((?!api|_next/static|_next/image|_img|favicon.ico|manifest.webmanifest|.*\\.(?:svg|png|jpg|jpeg|gif|webp|pdf|txt|vcf|xml|webm|mp4|map)$).*)',
|
||||
'/(de|en)/:path*',
|
||||
'/((?!api|_next/static|_next/image|_img|favicon.ico|admin|manifest.webmanifest|.*\\.(?:svg|png|jpg|jpeg|gif|webp|pdf|txt|vcf|xml|webm|mp4|map)$).*)',
|
||||
'/(de|en)/:path*',
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user