fix(mdx): robust parsing for payload data and ignore sentry pipe noise

This commit is contained in:
2026-07-17 15:18:35 +02:00
parent 402b5c30c6
commit 9c9663eb88
7 changed files with 71 additions and 15 deletions

View File

@@ -65,11 +65,8 @@ export async function getPostBySlug(slug: string, locale: string): Promise<PostD
const fileContent = await fs.readFile(filePath, 'utf-8');
const { data, content } = matter(fileContent);
// Fix MDX data props dropped by next-mdx-remote
// Payload serializes as data={{"items":...}} which Acorn treats as a Block statement.
const fixedContent = content.replace(/data=\{\{([\s\S]*?)\}\}/g, (match, p1) => {
return 'data="{' + p1.replace(/"/g, '&quot;') + '}"';
});
const { fixMdxDataProps } = await import('./mdx-utils');
const fixedContent = fixMdxDataProps(content);
let parsedContent = fixedContent;
try {

46
lib/mdx-utils.ts Normal file
View File

@@ -0,0 +1,46 @@
export function fixMdxDataProps(content: string): string {
let fixedContent = content;
let dataIndex = fixedContent.indexOf('data={{');
while (dataIndex !== -1) {
let openCount = 0;
let endIndex = -1;
const startObj = dataIndex + 6; // index of the first '{' in 'data={{'
for (let i = startObj; i < fixedContent.length; i++) {
if (fixedContent[i] === '{') {
openCount++;
} else if (fixedContent[i] === '}') {
openCount--;
if (openCount === 0) {
endIndex = i;
break;
}
}
}
if (endIndex !== -1) {
// jsonStr is the content INSIDE the outer curly braces
const jsonStr = fixedContent.substring(startObj + 1, endIndex);
const safeJsonStr = jsonStr.replace(/"/g, '&quot;');
const replacement = `data="{${safeJsonStr}}"`;
// We also need to consume the closing `}` of the `data={{`
const nextCharIndex = endIndex + 1;
const skipChars =
nextCharIndex < fixedContent.length && fixedContent[nextCharIndex] === '}' ? 2 : 1;
fixedContent =
fixedContent.substring(0, dataIndex) +
replacement +
fixedContent.substring(endIndex + skipChars);
dataIndex = fixedContent.indexOf('data={{', dataIndex + replacement.length);
} else {
// Malformed braces, prevent infinite loop
break;
}
}
return fixedContent;
}

View File

@@ -53,11 +53,8 @@ export async function getPageBySlug(slug: string, locale: string): Promise<PageD
const fileContent = await fs.readFile(filePath, 'utf-8');
const { data, content } = matter(fileContent);
// Fix MDX data props dropped by next-mdx-remote
// Payload serializes as data={{"items":...}} which Acorn treats as a Block statement.
const fixedContent = content.replace(/data=\{\{([\s\S]*?)\}\}/g, (match, p1) => {
return 'data="{' + p1.replace(/"/g, '&quot;') + '}"';
});
const { fixMdxDataProps } = await import('./mdx-utils');
const fixedContent = fixMdxDataProps(content);
let parsedContent = fixedContent;
try {

View File

@@ -39,11 +39,8 @@ export async function getProductBySlug(slug: string, locale: string): Promise<Pr
const fileContent = await fs.readFile(filePath, 'utf-8');
const { data, content } = matter(fileContent);
// Fix MDX data props dropped by next-mdx-remote
// Payload serializes as data={{"items":...}} which Acorn treats as a Block statement.
const fixedContent = content.replace(/data=\{\{([\s\S]*?)\}\}/g, (match, p1) => {
return 'data="{' + p1.replace(/"/g, '&quot;') + '}"';
});
const { fixMdxDataProps } = await import('./mdx-utils');
const fixedContent = fixMdxDataProps(content);
let parsedContent = fixedContent;
try {