Another unrelated issue I’m having with the Sanity Fetcher component. Is NOT working on server side →
We have the SanityFetcher component on a page, with this GROQ prop as dynamic value
`
*[_type == 'post' && slug.current == '${$ctx.params.slug}' && vertical-> slug.current == '${$ctx.params.vertical}']{ slug, title, content, pageSEO, vertical->}
as you can see it uses
$ctxwe noticed it is not working on server side… server returns
This is something we noticed on the console
ORIG GROQ *[_type == 'post' && slug.current == 'undefined' && vertical-> slug.current == 'undefined']{ slug, title, content, pageSEO, vertical->}
see how ctx stuff is undefined, and then we see this
ORIG GROQ *[_type == 'post' && slug.current == 'what-does-pet-insurance-cover' && vertical-> slug.current == 'pet-insurance']{ slug, title, content, pageSEO, vertical->}
which have the correct values.
Disabling javascript (and also doing a view-source) we can see that the final elements/components with the data are not served by server
see the “loadings”
I traced that to https://github.com/plasmicapp/plasmic/blob/master/plasmicpkgs/plasmic-sanity-io/src/sanity.tsx#L413
now the first part you see (string containing the groq) is actually just a text element with the same dynamic value we use for the SanityFetcher component… this was done to just see if we had a bug passing params to all the way down into the server, but this is actually showing the params are in good shape since the server returns that text correctly filled
Not sure what’s happening really
hardcoding the groq works fine (meaning replacing the ctx for just a hardcoded string on the query)
are we missing anything on the setup? it doesn’t really feel like that since the correct ctx params are returned by the server on those text components… so I’m not sure where to look…
Hey Sebastian! Are you using codegen or the headless API?
Hello Samuel,
headless API
my [[..catcall]].tsx
page… might help you also to understand my setup
/**
* For each page, pre-fetch the data we need to render it
*/
export const getStaticProps: GetStaticProps = async (context) => {
const { catchall } = context.params ?? {};
// Convert the catchall param into a path string
const plasmicPath =
typeof catchall === 'string'
? catchall
: Array.isArray(catchall)
? `/${catchall.join('/')}`
: '/';
const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
if (!plasmicData) {
// This is some non-Plasmic catch-all page
return {
props: {},
};
}
// This is a path that Plasmic knows about.
// Cache the necessary data fetched for the page.
const queryCache = await extractPlasmicQueryData(
<PlasmicRootProvider
loader={PLASMIC}
prefetchedData={plasmicData}
skipFonts={!!env.NEXT_PUBLIC_GOOGLE_FONT}
pageParams={context.params}
>
<PlasmicComponent component={plasmicData.entryCompMetas[0].displayName} />
</PlasmicRootProvider>
);
// Pass the data in as props.
return {
props: { plasmicData, queryCache },
};
};
/**
* Actually render the page!
*/
export default function CatchallPage(props: {
plasmicData?: ComponentRenderData;
queryCache?: Record<string, any>;
}) {
const { plasmicData, queryCache } = props;
const router = useRouter();
if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
return <Error statusCode={404} />;
}
const pageMeta = plasmicData.entryCompMetas[0];
return (
// Pass in the data fetched in getStaticProps as prefetchedData
<PlasmicRootProvider
loader={PLASMIC}
prefetchedData={plasmicData}
prefetchedQueryData={queryCache}
pageParams={pageMeta.params}
pageQuery={router.query}
skipFonts={!!env.NEXT_PUBLIC_GOOGLE_FONT}
Link={PlainLink}
>
{
// plasmicData.entryCompMetas[0].displayName contains the name
// of the component you fetched.
}
<PlasmicComponent component={pageMeta.displayName} />
</PlasmicRootProvider>
);
}
When you use dynamic pages, if you are depending on SSR, then you should be sure to have a getStaticPaths()
to include the paths for all the slugs you use for your dynamic page. For example, it might look like…
export const getStaticPaths: GetStaticPaths = async () => {
const pageModules = await PLASMIC.fetchPages();
const productSlugs = await getProductSlugs();
return {
paths: [
...pageModules.map((mod) => ({
params: {
catchall: mod.path.substring(1).split("/"),
},
})),
...productSlugs.map((slug: any) => ({
params: {
catchall: ["product", slug]
}
}))
],
fallback: "blocking",
};
}
You can find more information here https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths
But the paths that are not included are generate on request time and populating the cache after. So it should still be rendered by the server. That’s how nextjs works. Get server paths is not mandatory.
Is that NOT supported by sanity fetcher?
Right. You need to specify at least a getStaticPaths with fallback: 'blocking'
to indicate that the routes should be generated lazily.
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: "blocking",
};
};
Still wouldn’t be the case because when i hardcoded the groq query with the actual string and not using ctx, it worked fine without any change to getstaticprops
@productive_duck can you verify whether things are working from a brand new create-plasmic-app? To help us narrow down the problem
this is my getStaticPaths
export const getStaticPaths: GetStaticPaths = async () => {
const pages = await PLASMIC.fetchPages();
return {
paths: pages.map((page) => ({
params: { catchall: page.path.substring(1).split('/') },
})),
fallback: 'blocking',
};
};
@yang I could try creating a new app, but how do you want me to configure the catchall page. also I need to port a code component from the other project
The new project should already include a working catch all page
You can ignore the code component, we would just render nothing in its place