@croct/plug-react
Version:
React components and hooks to plug your React applications into Croct.
71 lines (70 loc) • 2.33 kB
JavaScript
"use client";
import { useEffect, useMemo, useState } from "react";
import { getSlotContent } from "@croct/content";
import { useLoader } from "./useLoader.js";
import { useCroct } from "./useCroct.js";
import { isSsr } from "../ssr-polyfills.js";
import { hash } from "../hash.js";
function useCsrContent(id, options = {}) {
const {
cacheKey,
expiration,
fallback: fallbackContent,
initial: initialContent,
staleWhileLoading = false,
preferredLocale,
...fetchOptions
} = options;
const normalizedLocale = normalizePreferredLocale(preferredLocale);
const defaultContent = useMemo(
() => getSlotContent(id, normalizedLocale) ?? void 0,
[id, normalizedLocale]
);
const fallback = fallbackContent === void 0 ? defaultContent : fallbackContent;
const [initial, setInitial] = useState(
() => initialContent === void 0 ? defaultContent : initialContent
);
const croct = useCroct();
const result = useLoader({
cacheKey: hash(
`useContent:${cacheKey ?? ""}:${id}:${normalizedLocale ?? ""}:${JSON.stringify(fetchOptions.attributes ?? {})}`
),
loader: () => croct.fetch(id, {
...fetchOptions,
...normalizedLocale !== void 0 ? { preferredLocale: normalizedLocale } : {},
...fallback !== void 0 ? { fallback } : {}
}).then(({ content }) => content),
initial,
expiration
});
useEffect(
() => {
if (staleWhileLoading) {
setInitial((current) => {
if (current !== result) {
return result;
}
return current;
});
}
},
[result, staleWhileLoading]
);
return result;
}
function useSsrContent(slotId, { initial, preferredLocale } = {}) {
const resolvedInitialContent = initial === void 0 ? getSlotContent(slotId, normalizePreferredLocale(preferredLocale)) ?? void 0 : initial;
if (resolvedInitialContent === void 0) {
throw new Error(
"The initial content is required for server-side rendering (SSR). For help, see https://croct.help/sdk/react/missing-slot-content"
);
}
return resolvedInitialContent;
}
function normalizePreferredLocale(preferredLocale) {
return preferredLocale !== void 0 && preferredLocale !== "" ? preferredLocale : void 0;
}
const useContent = isSsr() ? useSsrContent : useCsrContent;
export {
useContent
};