UNPKG

@croct/plug-react

Version:

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

78 lines (77 loc) 2.46 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( () => { const content = initialContent === void 0 ? defaultContent : initialContent; if (content === void 0) { return void 0; } return { content }; } ); 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 } : {} }), initial, expiration }); useEffect( () => { if (staleWhileLoading) { setInitial((current) => { if (current !== result) { return result; } return current; }); } }, [result, staleWhileLoading] ); return result; } function useSsrContent(slotId, options = {}) { const { initial, preferredLocale } = options; 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 { content: resolvedInitialContent }; } function normalizePreferredLocale(preferredLocale) { return preferredLocale !== void 0 && preferredLocale !== "" ? preferredLocale : void 0; } const useContent = isSsr() ? useSsrContent : useCsrContent; export { useContent };