Environment-aware lazy loader shim that defaults to `React.lazy` for non-Next.js hosts (Vite, esbuild, CRA) while supporting opt-in delegation to the real `next/dynamic` in Next.js environments. ## Key Components | Export | Type | Description | |--------|------|-------------| | `dynamic` | Default export | Drop-in lazy loader; delegates to `React.lazy` or registered `next/dynamic` | | `registerDynamic` | Named export | One-time registration to swap in the real `next/dynamic` at app init | | `DynamicOptions` | Interface | Subset of `next/dynamic` options (`loading`, `ssr`, `suspense`) | | `DynamicLoader

` | Type | Loader function returning `{ default: ComponentType }` or bare component | ## Usage Example **Non-Next.js host (Vite/CRA) — no setup required:** ```typescript import dynamic from '@flamingo-stack/openframe-frontend-core/next-dynamic' // Callers must be wrapped in a boundary const HeavyWidget = dynamic(() => import('./HeavyWidget')) ``` **Next.js host — register once at app init:** ```typescript // lib/embed-shim-registration.ts import nextDynamic from 'next/dynamic' import { registerDynamic } from '@flamingo-stack/openframe-frontend-core/embed-shims' registerDynamic(nextDynamic) ``` **With options (Next.js only — ignored on React.lazy fallback):** ```typescript const Chart = dynamic(() => import('./Chart'), { ssr: false, loading: ({ isLoading }) => isLoading ? : null, }) ``` > **Note:** `ssr` and `loading` options are silently ignored when running on the `React.lazy` fallback. Consumers relying on those options must call `registerDynamic` first. All call sites must have a `` boundary in the component tree.