All questions

Sanity + Remix, what is the supported Croct integration path?

Asked by Darius King on

DKDarius King

We run a Sanity-backed marketing site on Remix. Looking at the Croct docs I see SDKs for Next.js, React, Vue, and Nuxt, but nothing Remix-specific.

My instinct as a Remix dev is that everything belongs in the loader:

export async function loader({request}: LoaderFunctionArgs) {    const hero = await getPersonalizedHero(request);    return json({hero});}

So the question is whether I should fetch from Croct in loaders via the HTTP API, or just drop the React SDK into the components client-side. Is one of these the supported path or are both fine

Was this helpful?

2 answers

RNRachel NunesAccepted answer

Both work, and your loader instinct is the better default. There is no dedicated Remix SDK today; the documented SDKs are JavaScript, React, Next.js, Vue, Nuxt, and PHP. For Remix that leaves two paths:

Server-side, call the HTTP Content API from the loader. POST to /external/web/content on api.croct.io with your slot ID and a context object. One requirement that trips people up: context.page.url is mandatory, so pass it from the request:

export async function loader({request}: LoaderFunctionArgs) {    const response = await fetch('https://api.croct.io/external/web/content', {        method: 'POST',        headers: {'X-Api-Key': process.env.CROCT_API_KEY},        body: JSON.stringify({            slotId: 'home-hero',            context: {page: {url: request.url}},        }),    });
    return json({hero: await response.json()});}

Pages then arrive personalized, with nothing to swap on the client.

Client-side, @croct/plug-react works fine in Remix, but content resolves after load, so the default renders first and the personalized version swaps in. For a marketing site I would keep content in loaders and use the React SDK only for event tracking. Either way your Sanity document remains the fallback when no experience applies.

Was this helpful?
DKDarius King

Loader path it is. The context.page.url requirement would have cost me an hour, appreciate the heads up.

Mmbecker

Small addition if you go the loader route: wrap the fetch with a timeout and a catch that returns your Sanity content directly. Then a slow or failed personalization call degrades to the default copy instead of delaying the whole document response. Same fallback philosophy the SDKs give you, just explicit in your own code.

Was this helpful?
Still have questions?