You can manually install @plasmicapp/query
and implement their extractPlasmicQueryData
method.
It could be something like:
// data/data.tsx
export async function extractPlasmicQueryData(
element: React.ReactElement
): Promise<Record<string, any>> {
const cache = new Map<string, any>();
try {
await prepass(
<PlasmicPrepassContext cache={cache}>{element}</PlasmicPrepassContext>
);
} catch (err) {
console.warn(`PLASMIC: Error encountered while pre-rendering`, err);
}
return Object.fromEntries(
Array.from(cache.entries()).filter(
([key, val]) => !key.startsWith("$swr$") && val !== undefined
)
);
}
And then you can use it normally when rendering the pages (you can use PlasmicQueryDataProvider
directly):
// pages/myPage.tsx
import { PlasmicQueryDataProvider } from "@plasmicapp/query";
import * as React from "react";
import { PlasmicMyPage } from "../components/plasmic/PlasmicMyPage";
import { extractPlasmicQueryData } from "../data/data";
export async function getStaticProps() {
const queryCache = await extractPlasmicQueryData(<PlasmicMyPage />);
return { props: { queryCache } };
}
function MyPage({ queryCache }: Record<string, any>) {
return (
<PlasmicQueryDataProvider prefetchedCache={queryCache}>
<PlasmicMyPage />
</PlasmicQueryDataProvider>
);
}
export default MyPage;
You can also ignore extractPlasmicQueryData
and use plasmicPrepass
instead, to integrate it with your own fetching framework instead of react-swr.
(react-swr is what's used by the components from the Plasmic component store, so use that for pages where you want component store components to Just Work.)
You can add a GenericErrorBoundary
to fetch as much data as possible even in the face of rendering errors.
// data/data.tsx
import { PlasmicPrepassContext } from "@plasmicapp/query";
import React from "react";
import prepass from "react-ssr-prepass";
export async function extractPlasmicQueryData(
element: React.ReactElement
): Promise<Record<string, any>> {
const cache = new Map<string, any>();
try {
await plasmicPrepass(
<PlasmicPrepassContext cache={cache}>{element}</PlasmicPrepassContext>
);
} catch (err) {
console.warn(`PLASMIC: Error encountered while pre-rendering`, err);
}
return Object.fromEntries(
Array.from(cache.entries()).filter(
([key, val]) => !key.startsWith("$swr$") && val !== undefined
)
);
}
/**
* Runs react-ssr-prepass on `element`
*/
async function plasmicPrepass(element: React.ReactElement) {
await prepass(buildPlasmicPrepassElement(element));
}
/**
* Unfortunately in codegen we can't check for `PlasmicComponent` instances,
* making it harder to isolate components in error boudaries to fetch as much
* data as possible.
*/
function buildPlasmicPrepassElement(element: React.ReactElement) {
return <GenericErrorBoundary>{element}</GenericErrorBoundary>;
}
class GenericErrorBoundary extends React.Component<{
children: React.ReactNode;
}> {
constructor(props: { children: React.ReactNode }) {
super(props);
}
componentDidCatch(error: any) {
console.log(`Plasmic: Encountered error while prepass rendering:`, error);
}
render() {
return this.props.children;
}
}