UNPKG

@croct/plug-react

Version:

React components and hooks to plug your React applications into Croct.

71 lines (70 loc) 2.33 kB
"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 };