Hey there,
I have some content relationships within my prismic repo, but need the actual underlying linked type instead of just a metadata block about the object.
Is there a way to hydrate this with the actual objects already? Or do I need to do it myself?
Okie dokie.
I worked out a way to hydrate the list of items.
Using Remix Run.
Page:
import {SliceZone} from "@prismicio/react";
import {useLoaderData} from "@remix-run/react";
import type {LoaderFunction} from "@remix-run/cloudflare";
import {json} from "@remix-run/cloudflare";
import {addPrismicDocToCache, getCachedDataByUID} from "~/utils/prismic.server";
import {components} from '../../slices';
import {hydrateDocumentSlices} from "~/utils/hydrateDocumentSlices";
export const loader: LoaderFunction = async ({params}) => {
const customType = 'page';
const uid = params.page as string;
try {
const doc = await getCachedDataByUID(customType, uid);
addPrismicDocToCache(uid, doc);
const hydratedSlices = await hydrateDocumentSlices(doc.data);
return json(hydratedSlices);
} catch(error) {
console.error(error);
throw new Response("Not", {
status: 404,
});
}
};
export default function Index() {
const data = useLoaderData();
return (<SliceZone slices={data.slices} components={components}/>);
}
prismic.server
... client stuff...
export async function getByID(id: string) {
return client.getByID(id);
}
hydrateDocumentSlices.ts
import type {FilledContentRelationshipField} from "@prismicio/types";
import {getByID} from "~/utils/prismic.server";
export const hydrateDocumentSlices = async (document: Record<string, any>) => {
document.slices = await Promise.all(document.slices.map(async (slice: any) => {
slice.items = await Promise.all(slice.items.map(async (document: Record<string, FilledContentRelationshipField>) => {
return await hydrateDocument(document);
}));
return slice;
}));
return document;
};
const hydrateDocument = async (document: Record<string, FilledContentRelationshipField> = {}) => {
const keys = Object.keys(document);
const values = Object.values(document);
return await Promise.all(keys.map(async (key, index) => {
const originalValue = values[index];
const documentID = document[key].id;
try {
return await getByID(documentID);
} catch(e) {
console.error('originalValue due to error', e);
return originalValue;
}
}));
};