Components
The SDK provides two main components for rendering dynamic content: DynamicComponent for individual components and MiniappComponent for collections of components.
DynamicComponent
Renders a server-driven component by name. This is the primary way to display dynamic content in your app.
Basic Usage
import { DynamicComponent } from '@dpage-ai/react-native-dpage';
// Simple usage
<DynamicComponent name="ProductCard" />
// With data props
<DynamicComponent
name="ProductCard"
data={{ productId: '123', showPrice: true }}
/>
// With custom project (overrides global config)
<DynamicComponent
name="ProductCard"
projectId="different-project"
/>Per-render Runtime Overrides
In advanced cases (like edit mode), you can override runtime deps for a specific render. Overrides are merged on top of the default + registered deps, and override existing keys if they collide.
Keep overrides object identity stable
useMemo.import React, { useMemo } from 'react';
import { DynamicComponent } from '@dpage-ai/react-native-dpage';
function Screen() {
// ✅ Stable identity
const editModeDeps = useMemo(
() => ({
View: EditableView,
Text: EditableText,
}),
[]
);
return (
<DynamicComponent
name="ProductCard"
runtimeDepsOverrides={editModeDeps}
/>
);
}Custom Loading & Error States
<DynamicComponent
name="ProductCard"
data={{ productId: '123' }}
renderLoading={() => (
<View style={styles.loading}>
<ActivityIndicator size="large" color="#3B82F6" />
<Text>Loading product...</Text>
</View>
)}
renderError={(error) => (
<View style={styles.error}>
<Text style={styles.errorText}>Failed to load</Text>
<Text>{error.message}</Text>
<Button title="Retry" onPress={() => {/* retry logic */}} />
</View>
)}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
name* | string | - | Component name/key to load |
data | object | - | Props to pass to the dynamic component |
projectId | string | - | Override global project ID |
miniappId | string | - | Miniapp ID for error reporting and cache scoping. When provided, runtime errors are automatically reported. |
miniappVersion | string | - | Miniapp version included in error reports for debugging |
renderLoading | () => ReactNode | - | Custom loading state renderer |
renderError | (error) => ReactNode | - | Custom error state renderer |
runtimeDepsOverrides | Record<string, unknown> | - | Per-render runtime deps overrides (merged on top of default + registered deps). Keep object identity stable to avoid recompilation. |
MiniappComponent
Renders a miniapp (collection of components) by ID. Useful for loading complete flows or screens with multiple components.
Basic Usage
import { MiniappComponent } from '@dpage-ai/react-native-dpage';
<MiniappComponent
miniappId="checkout-flow"
renderLoading={() => <LoadingView />}
renderError={(error) => <ErrorView error={error} />}
onLoaded={(result) => console.log('Miniapp loaded:', result)}
/>Per-render Runtime Overrides
Apply overrides to all components inside a miniapp (useful for edit mode):
import React, { useMemo } from 'react';
import { MiniappComponent } from '@dpage-ai/react-native-dpage';
function MiniappPreview({ miniappId }: { miniappId: string }) {
const editModeDeps = useMemo(
() => ({
Modal: InlineModal,
}),
[]
);
return (
<MiniappComponent
miniappId={miniappId}
runtimeDepsOverrides={editModeDeps}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
miniappId* | string | - | Miniapp identifier to load |
renderLoading | () => ReactNode | - | Custom loading state renderer |
renderError | (error) => ReactNode | - | Custom error state renderer |
onLoaded | (result) => void | - | Callback when miniapp finishes loading |
runtimeDepsOverrides | Record<string, unknown> | - | Per-render runtime deps overrides (merged on top of default + registered deps). Keep object identity stable to avoid recompilation. |
ErrorBoundary
A React error boundary component for catching runtime errors in miniapps. Both MiniappComponent and DynamicComponent automatically include an ErrorBoundary with proper miniapp context for error reporting, so you typically don't need to use this directly.
When to use ErrorBoundary directly
ErrorBoundary directly only when you need:- Custom retry/go-back handlers with the default error UI
- To wrap custom content outside of
MiniappComponent/DynamicComponent
Basic Usage
import { ErrorBoundary } from '@dpage-ai/react-native-dpage';
// With custom retry/go-back handlers (shows default error UI with buttons)
<ErrorBoundary
miniappId="checkout-flow"
miniappVersion="1.0.0"
onRetry={() => setRetryKey(k => k + 1)}
onGoBack={() => navigation.goBack()}
>
<MyCustomContent />
</ErrorBoundary>
// With custom fallback UI
<ErrorBoundary
miniappId="checkout-flow"
fallback={(error, reset) => (
<View>
<Text>Error: {error.message}</Text>
<Button onPress={reset} title="Try Again" />
</View>
)}
>
<MyCustomContent />
</ErrorBoundary>Props
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | - | Content to render |
miniappId | string | - | Miniapp ID for automatic error reporting. When provided, errors are sent to the DPage server. |
miniappVersion | string | - | Miniapp version included in error reports |
fallback | (error, reset) => ReactNode | - | Custom error UI. Receives the error and a reset function to retry. |
onError | (error, componentStack) => void | - | Callback when an error is caught. Called in addition to automatic reporting. |
onRetry | () => void | - | Called when "Try Again" is pressed. Shows the button when provided. |
onGoBack | () => void | - | Called when "Go Back" is pressed. Shows the button when provided. |
reportErrors | boolean | - | Enable/disable error reporting for this boundary. Defaults to true when miniappId is set. |
Automatic Error Reporting
Both MiniappComponent and DynamicComponent include built-in error boundaries that automatically report runtime errors to the DPage server when a miniappId is provided. This helps you monitor miniapp health in production.
// MiniappComponent - error reporting enabled automatically
<MiniappComponent
miniappId="checkout-flow"
renderError={(error) => <MyErrorUI error={error} />}
/>
// DynamicComponent within a miniapp context
const { rootComponentKey, version } = await loadMiniappComponents(miniappId);
<DynamicComponent
name={rootComponentKey}
miniappId={miniappId}
miniappVersion={version}
renderError={(error) => <MyErrorUI error={error} />}
/>To disable error reporting globally, set errorReporting: false in your initDPage config:
initDPage({
projectId: 'my-project',
apiToken: 'dpage_live_xxx',
errorReporting: false, // Disable all automatic error reporting
});Pro Tip
renderLoading and renderError props to match your app's design language.Loading States
Components show a default loading spinner when fetching. Customize this with renderLoading to match your app's design:
import { View, ActivityIndicator, Text, StyleSheet } from 'react-native';
const CustomLoader = () => (
<View style={styles.container}>
<ActivityIndicator size="large" color="#3B82F6" />
<Text style={styles.text}>Loading component...</Text>
</View>
);
<DynamicComponent
name="MyComponent"
renderLoading={() => <CustomLoader />}
/>Composing Components
Combine multiple dynamic components in your layouts:
function ProductScreen({ productId }: { productId: string }) {
return (
<ScrollView>
<DynamicComponent
name="ProductHeader"
data={{ productId }}
/>
<DynamicComponent
name="ProductImages"
data={{ productId }}
/>
<DynamicComponent
name="ProductDetails"
data={{ productId }}
/>
<DynamicComponent
name="ProductReviews"
data={{ productId }}
/>
</ScrollView>
);
}