strapi-nextgen-framework
Version:
Production-ready, type-safe framework bridging Strapi v4 CMS and Next.js 14+ App Router with automatic cache management, Error Boundaries, and SEO optimization
84 lines • 3.88 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StrapiRenderer = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const error_boundary_1 = require("./error-boundary");
const validator_1 = require("./validator");
/**
* Renders Strapi dynamic zones with automatic component mapping
*
* Features:
* - Automatic Error Boundary wrapping for each component
* - Optional Zod validation in development mode
* - Graceful degradation in production
* - Type-safe component mapping
*
* @param props - Renderer configuration
*
* @example
* ```tsx
* <StrapiRenderer
* data={dynamicZoneData}
* map={componentMap}
* validation="warn"
* />
* ```
*/
function StrapiRenderer(props) {
const { data, map, validation = process.env.NODE_ENV === 'development' ? 'error' : 'silent', fallback, onError, } = props;
// Handle empty or invalid data
if (!data || !Array.isArray(data)) {
if (process.env.NODE_ENV === 'development') {
console.warn('[StrapiRenderer] Invalid data prop: expected array, got:', typeof data);
}
return fallback ? (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: fallback }) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
}
// Handle empty array
if (data.length === 0) {
return fallback ? (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: fallback }) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
}
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: data.map((item, index) => {
// Type guard: ensure item is an object
if (typeof item !== 'object' || item === null) {
if (process.env.NODE_ENV === 'development') {
console.error('[StrapiRenderer] Invalid component data:', item);
}
return null;
}
const component = item;
// Extract component type from __component field
const componentType = component.__component;
if (typeof componentType !== 'string') {
if (process.env.NODE_ENV === 'development') {
console.error('[StrapiRenderer] Component missing __component field:', component);
}
return null;
}
// Look up component in map
const mapEntry = map[componentType];
if (!mapEntry) {
if (process.env.NODE_ENV === 'development') {
console.error(`[StrapiRenderer] No component mapped for type: ${componentType}`, '\nAvailable mappings:', Object.keys(map));
}
return null;
}
const { component: Component, schema } = mapEntry;
// Validate component data with Zod schema (if provided)
if (schema && validation !== 'silent') {
const validationResult = (0, validator_1.validateComponentData)(component, schema, componentType, validation);
// If validation failed and mode is 'error', skip rendering
if (!validationResult.success && validation === 'error') {
return null;
}
}
// Generate unique key for component
const componentId = component.id;
const key = (typeof componentId === 'string' || typeof componentId === 'number')
? componentId
: `${componentType}-${index}`;
// Render component wrapped in Error Boundary
return ((0, jsx_runtime_1.jsx)(error_boundary_1.ComponentErrorBoundary, { componentType: componentType, onError: onError, fallback: fallback, children: (0, jsx_runtime_1.jsx)(Component, { ...component }) }, key));
}) }));
}
exports.StrapiRenderer = StrapiRenderer;
//# sourceMappingURL=index.js.map