UNPKG

@ai-growth/nextjs

Version:

Seamlessly integrate Sanity CMS with Next.js applications for automated blog routing and rendering

170 lines (169 loc) 7.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useIsCmsRoute = exports.useCmsRouteState = exports.CmsRouteHandler = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const router_1 = require("next/router"); const DefaultTemplate_1 = require("./DefaultTemplate"); const cms_content_1 = require("../utils/cms-content"); const route_config_1 = require("../utils/route-config"); /** * CMS Route Handler for Next.js App Router * * This component handles CMS routing by checking if the current route is a CMS route, * fetching content accordingly, and rendering the appropriate template or children. */ const CmsRouteHandler = ({ children, customTemplate, loadingComponent, errorComponent, contentOptions = {}, className, showLoading = true, showErrors = true, onRouteChange, onContentLoaded, onContentError, }) => { const router = (0, router_1.useRouter)(); const [state, setState] = (0, react_1.useState)({ isCmsRoute: false, isLoading: false, currentSlug: '', content: null, error: null, }); // Fetch content for CMS routes const fetchContent = (0, react_1.useCallback)(async (path) => { setState(prev => ({ ...prev, isLoading: true, error: null })); try { const result = await (0, cms_content_1.validateContentRoute)(path, contentOptions); if (result.isValid && result.content) { setState(prev => ({ ...prev, isLoading: false, content: result.content || null, error: null, })); onContentLoaded?.(result.content); } else { const errorMessage = result.error || 'Content not found'; setState(prev => ({ ...prev, isLoading: false, content: null, error: errorMessage, })); onContentError?.(errorMessage); } } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; setState(prev => ({ ...prev, isLoading: false, content: null, error: errorMessage, })); onContentError?.(errorMessage); } }, [contentOptions, onContentLoaded, onContentError]); // Handle route changes (0, react_1.useEffect)(() => { if (!router.isReady) return; const currentPath = router.asPath; const isCms = (0, route_config_1.isValidCmsRoute)(currentPath); // Avoid unnecessary updates if (state.currentSlug === currentPath && state.isCmsRoute === isCms) { return; } setState(prev => ({ ...prev, isCmsRoute: isCms, currentSlug: currentPath, })); onRouteChange?.(currentPath, isCms); if (isCms) { fetchContent(currentPath); } }, [router.isReady, router.asPath, state.currentSlug, state.isCmsRoute, onRouteChange]); // Separate effect for fetchContent to avoid dependency issues (0, react_1.useEffect)(() => { if (state.isCmsRoute && state.currentSlug && !state.isLoading && !state.content && !state.error) { fetchContent(state.currentSlug); } }, [state.isCmsRoute, state.currentSlug, state.isLoading, state.content, state.error, fetchContent]); // Retry function const handleRetry = (0, react_1.useCallback)(() => { if (state.currentSlug) { fetchContent(state.currentSlug); } }, [state.currentSlug, fetchContent]); // If router is not ready, render children if (!router.isReady) { return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children }); } // If not a CMS route, render children if (!state.isCmsRoute) { return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children }); } // CMS route handling const TemplateComponent = customTemplate || DefaultTemplate_1.DefaultTemplate; // Show loading state if (state.isLoading && showLoading) { if (loadingComponent) { return (0, jsx_runtime_1.jsx)("div", { className: className, children: loadingComponent }); } return ((0, jsx_runtime_1.jsx)("div", { className: className, children: (0, jsx_runtime_1.jsx)(TemplateComponent, { content: null, isLoading: true, error: "", onRetry: handleRetry }) })); } // Show error state if (state.error && showErrors) { if (errorComponent) { const ErrorComponent = errorComponent; return ((0, jsx_runtime_1.jsx)("div", { className: className, children: (0, jsx_runtime_1.jsx)(ErrorComponent, { error: state.error, onRetry: handleRetry }) })); } return ((0, jsx_runtime_1.jsx)("div", { className: className, children: (0, jsx_runtime_1.jsx)(TemplateComponent, { content: null, isLoading: false, error: state.error, onRetry: handleRetry }) })); } // Show content if (state.content) { return ((0, jsx_runtime_1.jsx)("div", { className: className, children: (0, jsx_runtime_1.jsx)(TemplateComponent, { content: state.content, isLoading: false, error: "", onRetry: handleRetry }) })); } // Fallback: render children if no CMS content and not showing errors if (!showErrors) { return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children }); } // Default fallback return ((0, jsx_runtime_1.jsx)("div", { className: className, children: (0, jsx_runtime_1.jsx)(TemplateComponent, { content: null, isLoading: false, error: "", onRetry: handleRetry }) })); }; exports.CmsRouteHandler = CmsRouteHandler; // Hooks para compatibilidade com testes existentes const useCmsRouteState = () => { const router = (0, router_1.useRouter)(); const [state, setState] = (0, react_1.useState)({ isCmsRoute: false, isLoading: false, currentSlug: '', content: null, error: null, }); (0, react_1.useEffect)(() => { if (!router.isReady) return; const currentPath = router.asPath; const isCms = (0, route_config_1.isValidCmsRoute)(currentPath); setState(prev => ({ ...prev, isCmsRoute: isCms, currentSlug: currentPath, })); }, [router.isReady, router.asPath]); return state; }; exports.useCmsRouteState = useCmsRouteState; const useIsCmsRoute = () => { const router = (0, router_1.useRouter)(); const [isCmsRoute, setIsCmsRoute] = (0, react_1.useState)(false); (0, react_1.useEffect)(() => { if (!router.isReady) { setIsCmsRoute(false); return; } const currentPath = router.asPath; const isCms = (0, route_config_1.isValidCmsRoute)(currentPath); setIsCmsRoute(isCms); }, [router.isReady, router.asPath]); return isCmsRoute; }; exports.useIsCmsRoute = useIsCmsRoute; exports.default = exports.CmsRouteHandler;