@gravity-ai/react-native
v0.1.0
Published
React Native components for rendering Gravity AI advertisements
Readme
@gravity-ai/react-native
React Native rendering for Gravity server-driven PSP-1 ads.
npm i @gravity-ai/react-native react react-nativereact (>=18.2) and react-native (>=0.76) are peer dependencies and are
never bundled. The package has no DOM or react-dom dependency.
import { GravityAd, GravityThemeProvider } from '@gravity-ai/react-native';
<GravityThemeProvider>
<GravityAd ad={ad} onClickTracked={() => analytics.track('ad_click')} />
</GravityThemeProvider>RN renders the portable PSP-1 profile, not the web/CSS profile. When
requesting ads, send supportsSpec: true and specCapabilities: 'psp1' so
the API returns specs this package can paint. The exported
GRAVITY_RN_SPEC_OPTIONS object can be spread into either API request shape:
import { GRAVITY_RN_SPEC_OPTIONS } from '@gravity-ai/react-native';
const ads = await client.getAd({
...params,
...GRAVITY_RN_SPEC_OPTIONS,
});
const result = await gravityAds(req, messages, placements, {
...GRAVITY_RN_SPEC_OPTIONS,
});GravityAd uses a valid server renderer_spec unless variant pins a host
variant, then falls back to a small native card. The spec must be structurally
valid, PSP-1 conformant, and produce content for the supplied ad; otherwise
the built-in card is used. The whole card is tappable; nested spec links retain
their own destinations. A native impression fires once when at least 50% of
the ad's measured window area is visible, using fetch(impUrl). Measurement
is retried periodically while the ad is armed, so ads mounted below the fold
in a ScrollView can still fire when they become visible. It starts at 500ms,
backs off to a maximum 1s cadence during the first 30 seconds off-screen, then
uses a 5s low-frequency floor. It resets to 500ms whenever layout or an
explicit visibility measurement signals that the surface may have moved. In a plain ScrollView, wire the returned
measureVisibility callback to onScroll. Polling pauses while the app is
backgrounded and resumes at the responsive cadence when the app returns to the
foreground. Polling stops after the impression fires, when the ad changes, and
when the component unmounts. For virtualized lists, pass
isViewable from FlatList or SectionList's onViewableItemsChanged
callback as the host-authoritative visibility signal; it fires immediately and
disables polling for that render. useAdTracking also returns an imperative
measureVisibility callback for publishers who drive visibility from their own
onScroll handler. Tracking failures are swallowed.
GravityThemeProvider follows the device color scheme by default. Pass
theme={{ primary: '#...' }} to override semantic tokens. $token,
$token/45, hsl(var(--token)), and var(--radius) styles are understood.
nowrap uses one line with tail ellipsis. maxLines remains accepted for
PSP-1 compatibility but is intentionally not applied: ad copy is never
client-truncated unless the spec explicitly requests nowrap.
The prop names match @gravity-ai/react where they have RN meaning. Web-only
className and openInNewTab are intentionally omitted; RN navigation uses
Linking.openURL.
