Gathering detailed insights and metrics for react-enhanced-suspense
Gathering detailed insights and metrics for react-enhanced-suspense
Gathering detailed insights and metrics for react-enhanced-suspense
Gathering detailed insights and metrics for react-enhanced-suspense
A React 19 component that enhances React's Suspense with promise resolved values handling, error handling, retry functionality of failing promises, and more.
npm install react-enhanced-suspense
Typescript
Module System
Node Version
NPM Version
73.5
Supply Chain
99
Quality
89.2
Maintenance
100
Vulnerability
100
License
TypeScript (99.27%)
JavaScript (0.73%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
2 Stars
55 Commits
1 Watchers
1 Branches
1 Contributors
Updated on May 25, 2025
Latest Version
4.0.3
Package Id
react-enhanced-suspense@4.0.3
Unpacked Size
125.26 kB
Size
19.39 kB
File Count
52
NPM Version
10.2.0
Node Version
20.16.0
Published on
May 25, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
A React 19 component that enhances React's Suspense
with optional features like promise resolved values handling (onSuccess
), error handling (onError
), retry functionality of failing promises (retry
), caching (cache
), and timeout fallbacks (timeouts
).
Suspense
(only fallback
and/or children
props)
onSuccess
onError
(*Client Only)retry
(*Client Only)cache
and resourceId
timeouts
And timeoutFallbacks
productionPropsErrorFallback
)
children
, The Resource PropresourceId
PropcacheAPI
To install the package, run:
1npm i react-enhanced-suspense
You can import the component in two ways:
Named import: Use this if you prefer explicit names:
1import { EnhancedSuspense } from "react-enhanced-suspense";
Default import: Use this for a shorter, more familiar syntax (like React’s Suspense
):
1import Suspense from "react-enhanced-suspense";
Both are the same component under the hood. Pick the one that suits your project!
This component can be used as a substitute for React's Suspense
.
Promise Resolution Handling: Use onSuccess
to transform resolved promise or React Context values.
(*)Error Handling: Use onError
to wrap React's Suspense
in an ErrorBoundary
for custom error rendering (Client only).
(*)Retry Functionality: Automatically retry failed promises with retry
, configurable with retryCount
, retryDelay
, retryBackoff
, and onRetryFallback
(Client only).
Caching: Store promise results in memory or localStorage
(or any custom storage) with cache
, resourceId
, cacheTTL
, cacheVersion
, and cachePersist
.
Timeout Fallbacks: Update the fallback UI dynamically with timeouts
and timeoutFallbacks
for long-running operations.
React's Suspense
: This component is React's Suspense
when only fallback
or children
props are used.
TypeScript Support: Fixes TypeScript errors when using React Context with Suspense
, unlike React’s native Suspense
.
(*): These props can only be used in the Client.
Suspense
(only fallback
and/or children
props)1import Suspense from "react-enhanced-suspense"; 2 3export default function Component({ promise }: { promise: Promise<string> }) { 4 return ( 5 <> 6 <div>Hey</div> 7 <div> 8 <Suspense fallback="Loading...">{promise}</Suspense> 9 </div> 10 </> 11 ); 12}
Can be used either in the Client or Server.
children
in React's SuspenseEnhancedSuspense
fixes a Typescript error that appears when using React Context as children
in React's Suspense
:
1"use client"; 2 3import Suspense from "react-enhanced-suspense"; 4import { createContext, Suspense as ReactSuspense } from "react"; 5 6const MyContext = createContext("Default value"); 7 8export default function ShowContext() { 9 return ( 10 <> 11 <Suspense>{MyContext}</Suspense> // <-- No Typescript error 12 <ReactSuspense>{MyContext}</ReactSuspense> // <-- Typescript error: Type 'Context<string>' is not assignable to type 'ReactNode'. 13 </> 14 ); 15}
onSuccess
1import Suspense from "react-enhanced-suspense"; 2 3export default function Component({ promise }: { promise: Promise<string[]> }) { 4 return ( 5 <> 6 <div>Hey</div> 7 <div> 8 <Suspense 9 fallback="Loading..." 10 onSuccess={(data) => data.map((item) => <div key={item}>{item}</div>)} 11 > 12 {promise} 13 </Suspense> 14 </div> 15 </> 16 ); 17}
Can be used either in the Client or Server.
Context
ExampleEnhancedSuspense
also supports React Context as a Usable
resource (children
prop):
1"use client"; 2 3import Suspense from "react-enhanced-suspense"; 4import { createContext } from "react"; 5 6const MyContext = createContext("Default value"); 7 8export default function Context() { 9 return ( 10 <Suspense onSuccess={(value) => <div>Context value: {value}</div>}> 11 {MyContext} 12 </Suspense> 13 ); 14}
This renders Context value: Default value
.
onError
(*Client Only)1"use client"; 2 3import Suspense from "react-enhanced-suspense"; 4 5export default function Component() { 6 return ( 7 <Suspense onError={(error) => <div>{error.message}</div>}> 8 { 9 new Promise((resolve, reject) => 10 setTimeout(() => reject("Failed"), 1000) 11 ) 12 } 13 </Suspense> 14 ); 15}
The onError
prop wraps React's Suspense
in an ErrorBoundary
component for custom error rendering. It always expects an Error
object, no matter what the rejected value of the promise is.
Can only be used in the Client.
retry
(*Client Only)With EnhancedSuspense
you can automatically retry failed promises with configurable options:
1"use client"; 2 3import Suspense from "react-enhanced-suspense"; 4 5export default function Component() { 6 return ( 7 <> 8 <div>Hey</div> 9 <Suspense 10 retry 11 retryCount={10} // number of retries; default: 1 12 retryDelay={500} // delay between retries in ms; default: 0 13 retryBackoff="linear" // backoff for retries; default: undefined 14 onRetryFallback={(attempt) => <div>{`Retrying ${attempt}...`}</div>} // fallback to show in each retry attempt; default: undefined 15 fallback="Loading..." // fallback to show on first attempt 16 > 17 {() => 18 new Promise<string[]>((resolve, reject) => { 19 setTimeout(() => { 20 if (Math.random() > 0.7) { 21 resolve(["Roger", "Alex"]); 22 } else { 23 reject("Fail on data fetching"); 24 } 25 }, 1000); 26 }) 27 } 28 </Suspense> 29 </> 30 ); 31}
When using retry
, the resource (the children
prop) should be a function returning a promise, rather than a promise itself. If not, the retries will be on the same initially rejected promise and would have no effect.
retryBackoff
admits the following values: linear
, exponential
, or a function with signature (attemptIndex:number, retryDelay:number)=>number
.
Works only in the Client.
cache
and resourceId
Cache promise results with cache
and resourceId
props:
1import Suspense from "react-enhanced-suspense"; 2 3export default function Component() { 4 return ( 5 <> 6 <div>Hey</div> 7 <Suspense 8 cache 9 cacheTTL={2000} // expiration time in ms for the cache; default: undefined 10 cacheVersion={1} // number, when this changes invalidates cache; default: undefined 11 cachePersist // whether to persist or not cache in localStorage; default: false 12 resourceId="my-promise" // the id of the resource; without it the cache takes no effect 13 > 14 { 15 new Promise<string[]>((resolve, reject) => { 16 setTimeout(() => { 17 if (Math.random() > 0.2) { 18 resolve(["Roger", "Alex"]); 19 } else { 20 reject("Fail on data fetching"); 21 } 22 }, 1000); 23 }) 24 } 25 </Suspense> 26 </> 27 ); 28}
Can be used either in the Client or the Server.
timeouts
And timeoutFallbacks
Update fallback UI for long-running operations:
1import Suspense from "react-enhanced-suspense"; 2 3const VERY_LONG_TIME = 15000; 4 5export default function Component() { 6 return ( 7 <Suspense 8 fallback="Loading..." 9 timeouts={[3000, 6000, 10000]} 10 timeoutFallbacks={[ 11 "Still working...", 12 "Taking longer...", 13 <div style={{ color: "green" }}>Almost there...</div>, 14 ]} 15 > 16 { 17 new Promise<string>((resolve) => 18 setTimeout(() => resolve("Done"), VERY_LONG_TIME) 19 ) 20 } 21 </Suspense> 22 ); 23}
Can be used either in the Client or the Server.
1"use client"; 2 3import Suspense from "react-enhanced-suspense"; 4 5export default function Component() { 6 return ( 7 <Suspense 8 retry 9 retryCount={15} 10 onRetryFallback={(attempt) => <div>{`Retry ${attempt}...`}</div>} 11 cache 12 cacheTTL={2000} 13 resourceId="my-promise" 14 onError={(error) => <div>{error.message}</div>} 15 onSuccess={(value) => value.map((item) => <div key={item}>{item}</div>)} 16 fallback="Loading..." 17 timeouts={[1000, 2000, 3000]} 18 timeoutFallbacks={["Three...", "Two...", "One..."]} 19 > 20 {() => 21 new Promise<string[]>((resolve, reject) => { 22 setTimeout(() => { 23 if (Math.random() > 0.9) { 24 resolve(["Roger", "Alex"]); 25 } else { 26 reject("Fail on data fetching"); 27 } 28 }, 4000); 29 }) 30 } 31 </Suspense> 32 ); 33}
onRetryFallback
takes precedence over timeouts
and timeoutFallbacks
. In the component above, from 0 to 1s, Loading...
will render. From 1s to 2s, Three...
; from 2s to 3s, Two...
; from 3s to 4s, One...
. Then, if promise is rejected, Retry 1...
will render for 4s, then, if rejected again, Retry 2...
, and so on, until promise is resolved or the number of retries are 15.
As always, when retry
is used, children
, the resource, should be a function returning a promise.
productionPropsErrorFallback
)When used in the Server, there are certain combination of props which are not allowed. This happens when the component is a React Client Component and has props which are functions. For example, resourceId
turns the component into a Client Component. If we use then onSuccess
, this is not allowed in the Server, because functions are not serializable.
1// In the Server 2{ 3 /* resourceId + onSuccess: ❌ BAD (React Client Component + Function) */ 4} 5<Suspense 6 resourceId="my-cache-key" 7 onSuccess={(data) => <div>{data}</div>} 8 productionPropsErrorFallback={ 9 <div>Component unavailable - please contact support</div> 10 } 11> 12 {promise} 13</Suspense>;
When this happens, that the component is a React Client Component and is used in the Server passing some prop as a function, the app will not crash. Instead, will show a message in development signaling that point, and in production will show either null
or, if provided, productionPropsErrorFallback
.
Other props that turns the component into a Client Component, apart from resourceId
, are timeouts
, onError
, retry
, cache
, and when children
, the resource, is a function. So when using onError
, or children
as a function, the component cannot be used in the Server (because it's a Client Component with props as functions).
But a Client Component can be used in the Server when no props are functions. For example, this is allowed in the Server:
1// In the Server 2{ 3 /* timeouts: ✅ React Client Component, no props as functions */ 4} 5<Suspense 6 fallback="Loading..." 7 timeouts={[3000, 6000, 10000]} 8 timeoutFallbacks={[ 9 <div>Timeout 1</div>, 10 <div>Timeout 2</div>, 11 <div>Timeout 3</div>, 12 ]} 13> 14 {promise} 15</Suspense>;
onSuccess
doesn't turn the component into a Client Component. So, despite it is a function, it can be used in the Server:
1// In the Server 2{ 3 /* onSuccess: ✅ React Server Component */ 4} 5<Suspense fallback="Loading..." onSuccess={(data) => <div>{data}</div>}> 6 {promise} 7</Suspense>;
cache
can also be used in the Server if children
is not a function (remember that cache
only works with resourceId
):
1// In the server 2{ 3 /* cache + resourceId: ✅ React Client Component, no props as functions */ 4} 5<Suspense fallback="Loading..." cache resourceId="my-promise" cachePersist> 6 {promise} 7</Suspense>;
Because retry
, in order to work properly, requires children
to be a function, cannot be used in the Server, and only in the Client.
Props | React Client Component | Server Allowed |
---|---|---|
children as a function | ✅ | ❌ |
onError | ✅ | ❌ |
timeouts | ✅ | ✅ if no props as function (e.g. ❌ with onSuccess ) |
resourceId | ✅ | ✅ if no props as function (e.g. ❌ with onSuccess ) |
retry | ✅ | ❌ because used with children as a function |
cache | ✅ | ✅ if no props as function (e.g. ❌ with onSuccess ) |
onSuccess | ❌ | ✅ |
fallback | ❌ | ✅ |
children not a function | ❌ | ✅ |
In the Client all props are allowed.
children
, The Resource Propchildren
is the resource. It can be either a ReactNode
, a Usable
(which is a promise or a React Context), or a function returning a promise. When used with onSuccess
, it can be a Usable
or a function returning a promise. When used without onSuccess
, it can be a ReactNode
, a Usable
that resolves to a ReactNode
, or a function returning a promise that resolves to a ReactNode
.
resourceId
PropAs has been stated, resourceId
turns the component into a Client Component, and it's necessary for cache
to take effect (it's the cache key for storing the value into memory or localStorage or custom storage). resourceId
it's a string. Apart from serving as a cache key when cache
is used, it is also useful when the resource, the children
prop, changes dynamically. When resourceId
changes, the evaluation of the resource is cancelled and a new evaluation starts. That is, a change in resourceId
triggers a new evaluation of the resource, cancelling any pending evaluations.
React's Suspense
evaluates the resource in every render if the resource is not memoized and it is not a state variable, that is, if it changes in every render. EnhancedSuspense
, on the other hand, in its Client version, doesn't need to memoize the resource. It is stable between rerenders. Therefore, if you want to reevalute a resource, you must supply a resourceId
and change it.
1"use client"; 2 3import Suspense from "react-enhanced-suspense"; 4import { useState, useEffect } from "react"; 5 6export default function Component() { 7 const [resource, setResource] = useState( 8 () => 9 new Promise<string[]>((resolve, reject) => { 10 setTimeout(() => { 11 if (Math.random() > 0.002) { 12 resolve(["Roger", "Alex"]); 13 } else { 14 reject("Fail on data fetching"); 15 } 16 }, 2000); 17 }) 18 ); 19 const [resourceId, setResourceId] = useState("first"); 20 const [isMounted, setIsMounted] = useState(false); 21 useEffect(() => { 22 setIsMounted(true); 23 }, []); 24 useEffect(() => { 25 if (!isMounted) return; 26 setResourceId("second"); 27 }, [resource]); 28 return ( 29 <> 30 <button 31 onClick={() => 32 setResource( 33 new Promise<string[]>((resolve, reject) => { 34 setTimeout(() => { 35 if (Math.random() > 0.002) { 36 resolve(["Alex", "Roger"]); 37 } else { 38 reject("Fail on data fetching"); 39 } 40 }, 2000); 41 }) 42 ) 43 } 44 > 45 change resource 46 </button> 47 <Suspense 48 fallback="Loading..." 49 onSuccess={(values) => 50 values.map((item) => <div key={item}>{item}</div>) 51 } 52 // Reevaluates the resource when pressing the button (not a Client Component) 53 > 54 {resource} 55 </Suspense> 56 <Suspense 57 fallback="Loading..." 58 resourceId="fixed" 59 onSuccess={(values) => 60 values.map((item) => <div key={item}>{item}</div>) 61 } 62 // DON'T Reevaluate the resource when pressing button (React Client Component + resourceId constant) 63 > 64 {resource} 65 </Suspense> 66 <Suspense 67 fallback="Loading..." 68 resourceId={resourceId} 69 onSuccess={(values) => 70 values.map((item) => <div key={item}>{item}</div>) 71 } 72 // Reevaluate the resource when pressing button (React Client Component + resourceId changes) 73 > 74 {resource} 75 </Suspense> 76 </> 77 ); 78}
The first Suspense
will reevaluate the resource when pressing the button because the props used doesn't turn it into a React Client Component (only fallback
, children
not being a function, and onSuccess
are used).
The second Suspense
will NOT reevaluate the resource despite pressing the button and changing it because resourceId
turns the component into a Client Component and is fixed (constant, doesn't change when pressing the button).
The third Suspense
will reevaluate the resource when pressing the button because of the useEffect
, that changes the resourceId
when the resource changes.
The correct way to implement it would be (a more realistic scenario):
1"use client"; 2 3import Suspense from "react-enhanced-suspense"; 4import { useState, useEffect } from "react"; 5 6export default function Component() { 7 const [prop, setProp] = useState(true); 8 const resource = prop 9 ? new Promise<string[]>((resolve, reject) => { 10 setTimeout(() => { 11 if (Math.random() > 0.002) { 12 resolve(["Roger", "Alex"]); 13 } else { 14 reject("Fail on data fetching"); 15 } 16 }, 2000); 17 }) 18 : new Promise<string[]>((resolve, reject) => { 19 setTimeout(() => { 20 if (Math.random() > 0.002) { 21 resolve(["Alex", "Roger"]); 22 } else { 23 reject("Fail on data fetching"); 24 } 25 }, 2000); 26 }); 27 const [resourceId, setResourceId] = useState(`my-promise-${prop}`); 28 useEffect(() => { 29 setResourceId(`my-promise-${prop}`); 30 }, [prop]); 31 return ( 32 <> 33 <button onClick={() => setProp((currentValue) => !currentValue)}> 34 Toggle prop 35 </button> 36 <Suspense 37 fallback="Loading..." 38 // Reevaluates the resource on EVERY RENDER (not a Client Component, resource not memoized and not a state variable) 39 > 40 {resource} 41 </Suspense> 42 <Suspense 43 fallback="Loading..." 44 resourceId="fixed" 45 // DON'T Reevaluate the resource on every render, NEITHER when the button is pressed. 46 > 47 {resource} 48 </Suspense> 49 <Suspense 50 fallback="Loading..." 51 resourceId={resourceId} 52 // DON'T Reevaluate the resource on every render, only WHEN the button is pressed. 53 > 54 {resource} 55 </Suspense> 56 </> 57 ); 58}
cacheAPI
Together with the component EnhancedSuspense
, a cacheAPI
is also exported:
1const cacheAPI: Readonly<{ 2 setCacheSizeLimit(bytes: number | null, entries?: number | null): void; 3 setCustomStorage(storage: CustomCacheStorage | null): void; 4 cleanupCache(): void; 5 startAutomaticCacheCleanup(intervalMs?: number): void; 6 stopAutomaticCacheCleanup(): void; 7 getCacheStatus(): { 8 isCustomStorage: boolean; 9 entryCount: number | undefined; 10 persistentCount: number | undefined; 11 expirationCount: number | undefined; 12 isCleanupActive: boolean; 13 }; 14 clearCache(options?: { clearLocalStorage?: boolean }): void; 15}>;
cleanupCache()
removes from cache all expired entries. clearCache()
clears all the cache. setCustomStorage
sets a custom storage for the cache, where:
1type CustomCacheStorage = { 2 get(key: string): CacheEntry | null; 3 set(key: string, value: any, ttl?: number, persist?: boolean): void; 4 delete(key: string): void; 5 cleanup?(): void; 6 clear?(): void; 7 status?(): 8 | { 9 entryCount?: number; 10 persistentCount?: number; 11 expirationCount?: number; 12 } 13 | undefined; 14};
and:
1type CacheEntry = { 2 value: any; 3 expiry?: number | undefined; 4};
These two types, CustomCacheStorage
and CacheEntry
are also exported by the package.
All props are optional. All props can be used together in the Client.
Prop | Description | Example | React Client Component | Server Allowed |
---|---|---|---|---|
onSuccess | A function that takes the resolved value of a resource (promise or React Context) and returns a ReactNode . When used, children must be a Usable (promise or React Context) or a function returning a promise. | <Suspense onSuccess={(values) => values.map(item => <div key={item}>{item}</div>)}>{new Promise<string[]>(resolve => setTimeout(() => resolve(["Roger", "Alex"]), 1000))}</Suspense> | ❌ | ✅ |
onError | A function that takes an Error and returns a ReactNode | <Suspense onError={(error) => <div>{error.message}</div>} /> | ✅ | ❌ |
children | A function that returns a promise, a ReactNode , or a Usable (promise or React Context). Specifies the resource or content that suspenses | <Suspense>{new Promise<string>(r => setTimeout(() => r("Done"), 1000))}</Suspense> | ✅ when is a function ❌ rest of cases | ❌ when is a function ✅ rest of cases |
fallback | A ReactNode | <Suspense fallback="Loading..." /> | ❌ | ✅ |
retry | A boolean that indicates whether to retry failing promises or not (default false ). When used, the resource should be a function returning a promise. | <Suspense retry>{() => new Promise((resolve, reject) => setTimeout(() => {if(Math.random() > 0.6){resolve(["Roger", "Alex"])}else{reject("Failed")}}, 1000))}</Suspense> | ✅ | ❌ because of used with children as a function |
retryCount | The number of retries to try when using retry (defaults to 1 ). Only applies when retry is used | <Suspense retry retryCount={15}>{...}</Suspense> | ✅ because of used with retry | ❌ because of used with children as a function |
retryDelay | The number of ms to apply (wait) between each retry (defaults to 0 ). Only applies when retry is used | <Suspense retry retryDelay={1000}>{...}</Suspense> | ✅ because of used with retry | ❌ because of used with children as a function |
retryBackoff | Specifies the backoff strategy to apply for retries (defaults undefined ). Can be "linear" , "exponential" , or a function with signature (attemptIndex: number, retryDelay: number) => number . Only applies when retry is used. | <Suspense retry retryBackoff="linear">{...}</Suspense> | ✅ because of used with retry | ❌ because of used with children as a function |
onRetryFallback | A function (with signature (retryAttempt: number) => ReactNode ) that specifies the fallback UI to be shown on each retry attempt. Only applies when retry is used. | <Suspense retry onRetryFallback={(retryAttempt) => <div>Retrying {retryAttempt}...</div>}>{...}</Suspense> | ✅ because of used with retry | ❌ because of used with children as a function |
resourceId | A string that identifies the resource being used. When used with cache serves as the cache key. Stabilizes the resource between rerenders. | <Suspense resourceId="my-promise">{new Promise<string>(r => setTimeout(() => r("Done"), 1000))}</Suspense> | ✅ | ✅ if no props as function (e.g. ❌ with onSuccess ) |
cache | A boolean that indicates whether to use the cache functionality or not. In order to work needs to be accompanied by resourceId , that serves as the cache key. | <Suspense cache cachePersist resourceId="my-promise">{new Promise<string>(r => setTimeout(() => r("Done"), 1000))}</Suspense> | ✅ | ✅ if no props as function (e.g. ❌ with onSuccess ) |
cacheTTL | A number that sets an expiration time in milliseconds for the cached value. Only applies when cache and resourceId are used. | <Suspense cache cachePersist cacheTTL={60000} resourceId="my-promise">{...}</Suspense> | ✅ because of used with cache and resourceId | ✅ if no props as function (e.g. ❌ with onSuccess ) |
cacheVersion | A number . Invalidates previous cached value when it's increased or decreased (changed). Only applies when cache and resourceId are used. | <Suspense cache cachePersist cacheTTL={60000} cacheVersion={cacheVersionKey} resourceId="my-promise">{...}</Suspense> | ✅ because of used with cache and resourceId | ✅ if no props as function (e.g. ❌ with onSuccess ) |
cachePersist | A boolean (defaults to false ) that indicates whether to persist the cached value into localStorage (or custom storage) or not. Only applies when cache and resourceId are used. | <Suspense cache cachePersist cacheTTL={60000} cacheVersion={cacheVersionKey} resourceId="my-promise">{...}</Suspense> | ✅ because of used with cache and resourceId | ✅ if no props as function (e.g. ❌ with onSuccess ) |
timeouts | A number[] . Timeouts in milliseconds to update fallback UI shown (onRetryFallback takes precedence). Only makes sense if timeoutFallbacks is used. | <Suspense timeouts={[1000, 2000]} timeoutFallbacks={["Two...", "One..."]} fallback="Loading...">{new Promise<string>(r => setTimeout(() => r("Go!"), 3000))}</Suspense> | ✅ | ✅ if no props as function (e.g. ❌ with onSuccess ) |
timeoutFallbacks | A ReactNode[] . Fallback UIs to show after each timeout specified in timeouts . Only makes sense if timeouts is not an empty array. | <Suspense timeouts={[1000, 2000]} timeoutFallbacks={["Two...", "One..."]} fallback="Loading...">{new Promise<string>(r => setTimeout(() => r("Go!"), 3000))}</Suspense> | ✅ Because used with timeouts | ✅ if no props as function (e.g. ❌ with onSuccess ) |
productionPropsErrorFallback | A ReactNode . Renders a custom fallback in production when invalid props are used in the Server (e.g. a React Client Component with props as functions in the Server). Defaults to null (renders nothing) if not provided. | <Suspense productionPropsErrorFallback={<div>component not available - contact support</div>}>{()=>Promise.resolve("Hey")}</Suspense> | ❌ | ✅ |
This project is licensed under the MIT License.
Copyright (c) 2025 Roger Gomez Castells (@roggc)
See the LICENSE file for details.
No vulnerabilities found.
No security vulnerabilities found.