fix: notion value.value return
reference: https://github.com/NotionX/react-notion-x/issues/681
This commit is contained in:
@@ -43,6 +43,58 @@ function extractPageReferencesFromRichText(
|
||||
return pageIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the block entries in a recordMap to ensure a consistent structure.
|
||||
*
|
||||
* The Notion API (via `getBlocks` / newer API responses) sometimes returns blocks
|
||||
* in a double-nested format:
|
||||
* { spaceId, value: { value: { id, type, ... }, role: "reader" } }
|
||||
*
|
||||
* But `react-notion-x` expects:
|
||||
* { value: { id, type, ... }, role: "reader" }
|
||||
*
|
||||
* This function flattens any double-nested entries so the renderer doesn't crash
|
||||
* when calling `uuidToId` on an undefined block id.
|
||||
*/
|
||||
export function normalizeRecordMap(recordMap: ExtendedRecordMap): void {
|
||||
// Normalize blocks
|
||||
for (const blockId of Object.keys(recordMap.block)) {
|
||||
const entry = recordMap.block[blockId] as any;
|
||||
if (
|
||||
entry?.value &&
|
||||
typeof entry.value === "object" &&
|
||||
entry.value.value &&
|
||||
typeof entry.value.value === "object" &&
|
||||
entry.value.value.id
|
||||
) {
|
||||
// Double-nested: flatten { value: { value: {...}, role }, spaceId } → { value: {...}, role }
|
||||
recordMap.block[blockId] = {
|
||||
value: entry.value.value,
|
||||
role: entry.value.role ?? entry.role ?? "reader",
|
||||
} as any;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize collections (same pattern can occur)
|
||||
if (recordMap.collection) {
|
||||
for (const collectionId of Object.keys(recordMap.collection)) {
|
||||
const entry = recordMap.collection[collectionId] as any;
|
||||
if (
|
||||
entry?.value &&
|
||||
typeof entry.value === "object" &&
|
||||
entry.value.value &&
|
||||
typeof entry.value.value === "object" &&
|
||||
entry.value.value.id
|
||||
) {
|
||||
recordMap.collection[collectionId] = {
|
||||
value: entry.value.value,
|
||||
role: entry.value.role ?? entry.role ?? "reader",
|
||||
} as any;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches missing page blocks that are referenced in rich text but not in the recordMap.
|
||||
* This fixes the issue where tables with multiple page links only show the first one.
|
||||
@@ -50,6 +102,9 @@ function extractPageReferencesFromRichText(
|
||||
export async function fetchMissingPageReferences(
|
||||
recordMap: ExtendedRecordMap,
|
||||
): Promise<void> {
|
||||
// Normalize first so we can safely access block.value.properties
|
||||
normalizeRecordMap(recordMap);
|
||||
|
||||
const allPageReferenceIds = new Set<string>();
|
||||
|
||||
// Iterate through all blocks to find page references in their properties
|
||||
@@ -81,6 +136,8 @@ export async function fetchMissingPageReferences(
|
||||
...newBlocks.recordMap.block,
|
||||
};
|
||||
}
|
||||
// Normalize again after merging new blocks (getBlocks may return double-nested format)
|
||||
normalizeRecordMap(recordMap);
|
||||
} catch (err) {
|
||||
console.warn("Failed to fetch missing page references:", err);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import notion from "@/lib/notion";
|
||||
import { addSignedUrls, fetchMissingPageReferences } from "@/lib/notion/utils";
|
||||
import {
|
||||
addSignedUrls,
|
||||
fetchMissingPageReferences,
|
||||
normalizeRecordMap,
|
||||
} from "@/lib/notion/utils";
|
||||
import { log } from "@/lib/utils";
|
||||
|
||||
export default async function handle(
|
||||
@@ -34,6 +38,9 @@ export default async function handle(
|
||||
// Fetch missing page references that are embedded in rich text (e.g., table cells with multiple page links)
|
||||
await fetchMissingPageReferences(recordMap);
|
||||
|
||||
// Normalize double-nested block structures from the Notion API
|
||||
normalizeRecordMap(recordMap);
|
||||
|
||||
// TODO: separately sign the file urls until PR merged and published; ref: https://github.com/NotionX/react-notion-x/issues/580#issuecomment-2542823817
|
||||
await addSignedUrls({ recordMap });
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@ import z from "zod";
|
||||
|
||||
import { fetchLinkDataById } from "@/lib/api/links/link-data";
|
||||
import notion from "@/lib/notion";
|
||||
import { addSignedUrls, fetchMissingPageReferences } from "@/lib/notion/utils";
|
||||
import {
|
||||
addSignedUrls,
|
||||
fetchMissingPageReferences,
|
||||
normalizeRecordMap,
|
||||
} from "@/lib/notion/utils";
|
||||
import { CustomUser, LinkWithDataroomDocument, NotionTheme } from "@/lib/types";
|
||||
|
||||
import LoadingSpinner from "@/components/ui/loading-spinner";
|
||||
@@ -236,6 +240,8 @@ export async function getStaticProps(context: GetStaticPropsContext) {
|
||||
recordMap = await notion.getPage(pageId, { signFileUrls: false });
|
||||
// Fetch missing page references that are embedded in rich text (e.g., table cells with multiple page links)
|
||||
await fetchMissingPageReferences(recordMap);
|
||||
// Normalize double-nested block structures from the Notion API
|
||||
normalizeRecordMap(recordMap);
|
||||
// TODO: separately sign the file urls until PR merged and published; ref: https://github.com/NotionX/react-notion-x/issues/580#issuecomment-2542823817
|
||||
await addSignedUrls({ recordMap });
|
||||
}
|
||||
|
||||
@@ -15,7 +15,11 @@ import z from "zod";
|
||||
import { fetchLinkDataById } from "@/lib/api/links/link-data";
|
||||
import { getFeatureFlags } from "@/lib/featureFlags";
|
||||
import notion from "@/lib/notion";
|
||||
import { addSignedUrls, fetchMissingPageReferences } from "@/lib/notion/utils";
|
||||
import {
|
||||
addSignedUrls,
|
||||
fetchMissingPageReferences,
|
||||
normalizeRecordMap,
|
||||
} from "@/lib/notion/utils";
|
||||
import {
|
||||
CustomUser,
|
||||
LinkWithDataroom,
|
||||
@@ -153,6 +157,8 @@ export const getStaticProps = async (context: GetStaticPropsContext) => {
|
||||
recordMap = await notion.getPage(pageId, { signFileUrls: false });
|
||||
// Fetch missing page references that are embedded in rich text (e.g., table cells with multiple page links)
|
||||
await fetchMissingPageReferences(recordMap);
|
||||
// Normalize double-nested block structures from the Notion API
|
||||
normalizeRecordMap(recordMap);
|
||||
await addSignedUrls({ recordMap });
|
||||
} catch (notionError) {
|
||||
const message =
|
||||
|
||||
@@ -13,7 +13,11 @@ import z from "zod";
|
||||
|
||||
import { fetchLinkDataByDomainSlug } from "@/lib/api/links/link-data";
|
||||
import notion from "@/lib/notion";
|
||||
import { addSignedUrls, fetchMissingPageReferences } from "@/lib/notion/utils";
|
||||
import {
|
||||
addSignedUrls,
|
||||
fetchMissingPageReferences,
|
||||
normalizeRecordMap,
|
||||
} from "@/lib/notion/utils";
|
||||
import { CustomUser, LinkWithDataroomDocument, NotionTheme } from "@/lib/types";
|
||||
|
||||
import LoadingSpinner from "@/components/ui/loading-spinner";
|
||||
@@ -246,6 +250,8 @@ export async function getStaticProps(context: GetStaticPropsContext) {
|
||||
recordMap = await notion.getPage(pageId, { signFileUrls: false });
|
||||
// Fetch missing page references that are embedded in rich text (e.g., table cells with multiple page links)
|
||||
await fetchMissingPageReferences(recordMap);
|
||||
// Normalize double-nested block structures from the Notion API
|
||||
normalizeRecordMap(recordMap);
|
||||
// TODO: separately sign the file urls until PR merged and published; ref: https://github.com/NotionX/react-notion-x/issues/580#issuecomment-2542823817
|
||||
await addSignedUrls({ recordMap });
|
||||
}
|
||||
|
||||
@@ -15,7 +15,11 @@ import z from "zod";
|
||||
import { fetchLinkDataByDomainSlug } from "@/lib/api/links/link-data";
|
||||
import { getFeatureFlags } from "@/lib/featureFlags";
|
||||
import notion from "@/lib/notion";
|
||||
import { addSignedUrls, fetchMissingPageReferences } from "@/lib/notion/utils";
|
||||
import {
|
||||
addSignedUrls,
|
||||
fetchMissingPageReferences,
|
||||
normalizeRecordMap,
|
||||
} from "@/lib/notion/utils";
|
||||
import {
|
||||
CustomUser,
|
||||
LinkWithDataroom,
|
||||
@@ -141,6 +145,8 @@ export const getStaticProps = async (context: GetStaticPropsContext) => {
|
||||
recordMap = await notion.getPage(pageId, { signFileUrls: false });
|
||||
// Fetch missing page references that are embedded in rich text (e.g., table cells with multiple page links)
|
||||
await fetchMissingPageReferences(recordMap);
|
||||
// Normalize double-nested block structures from the Notion API
|
||||
normalizeRecordMap(recordMap);
|
||||
await addSignedUrls({ recordMap });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user