mantis-recommender-react-native
v1.1.1
Published
React Native component library for Mantis content recommendations
Downloads
400
Readme
mantis-recommender-react-native
A React Native component library for rendering Mantis content recommendations with built-in theming, tracking, and error handling.
Note: This library requires an active integration with the Mantis Intelligence Recommender API. You'll need a valid API endpoint and component ID provided by Mantis Solutions to fetch recommendations. Contact your Mantis account manager for access.
Installation
npm install mantis-recommender-react-nativePeer Dependencies
Ensure your project has the following peer dependencies installed:
npm install react react-nativeQuick Start
Get recommendations rendering in under 5 minutes:
import React from 'react';
import { SafeAreaView } from 'react-native';
import { MantisRecommender } from 'mantis-recommender-react-native';
export default function App() {
return (
<SafeAreaView style={{ flex: 1 }}>
<MantisRecommender
apiUrl="https://claw.mantis-intelligence.com"
componentId="mantis-ui-widget-1"
url="https://www.mirror.co.uk"
title="Recommended for you"
onItemPress={(url) => console.log('Tapped:', url)}
/>
</SafeAreaView>
);
}Both named and default imports are supported:
// Named import (recommended)
import { MantisRecommender } from 'mantis-recommender-react-native';
// Default import
import MantisRecommender from 'mantis-recommender-react-native';Props API Reference
Required Props
| Prop | Type | Description |
| ------------- | -------- | ----------------------------------------------- |
| apiUrl | string | Base URL for the Mantis recommendations API |
| componentId | string | Unique identifier for this recommender instance |
| url | string | Page URL to get recommendations for |
Optional — API Parameters
| Prop | Type | Default | Description |
| ------------------- | ---------- | ------- | ------------------------------------------ |
| limit | number | — | Maximum number of recommendations to fetch |
| offset | number | — | Pagination offset |
| recommenderType | string | — | Type of recommender algorithm |
| adsEnabled | boolean | — | Enable ad slots in recommendations |
| adSlots | number[] | — | Positions for ad slots |
| age | number | — | Content age filter |
| tags | string[] | — | Filter by content tags |
| topics | string[] | — | Filter by content topics |
| language | string | — | Language filter |
| domain | string | — | Domain filter |
| subType | string | — | Content subtype filter |
| requireThumbnails | boolean | — | Only return items with thumbnails |
| mantisDebug | boolean | — | Enable debug mode |
Optional — Theming
| Prop | Type | Default | Description |
| ------------- | -------------------------- | ---------------------------- | ----------------------------------------------- |
| theme | 'light' \| 'dark' | 'light' | Built-in theme preset |
| title | string | 'Similar articles to this' | Section title displayed above the carousel |
| customTheme | DeepPartial<MantisTheme> | — | Partial theme overrides (deep-merged with base) |
Optional — Event Callbacks
| Prop | Type | Description |
| ------------------ | -------------------------------------------- | ------------------------------------------------------ |
| onDataRequested | () => void | Fired when a fetch begins |
| onDataProcessed | (data: DataResponseAgnostic) => void | Fired on successful fetch |
| onItemPress | (url: string) => void | Fired when a recommendation card is tapped |
| onError | (error: ErrorDataAgnosticResponse) => void | Fired on fetch error |
| onImpression | (event: TrackingEvent) => void | Fired when a card becomes visible (50%+ threshold) |
| onRendered | (event: TrackingEvent) => void | Fired once after items render successfully |
| trackingProvider | (event: TrackingEvent) => void | Universal tracking callback — receives all event types |
Optional — Secure Tracking
| Prop | Type | Default | Description |
| --------------------------- | --------- | -------------- | --------------------------------------- |
| secureEnabled | boolean | false | Enable secure server-side tracking |
| secureApi | string | — | Secure API URL (passed to config) |
| secureApiUrl | string | Production URL | Override the secure tracking endpoint |
| customerId | string | — | Customer identifier for secure tracking |
| impressionTrackingEnabled | boolean | — | Enable impression tracking |
| engagementSecuredEnabled | boolean | — | Enable engagement secured tracking |
Ref Methods
Access imperative methods via a ref:
import React, { useRef } from 'react';
import { MantisRecommender, type MantisRecommenderHandle } from 'mantis-recommender-react-native';
function App() {
const ref = useRef<MantisRecommenderHandle>(null);
return (
<>
<MantisRecommender ref={ref} apiUrl="..." componentId="..." url="..." />
<Button title="Refresh" onPress={() => ref.current?.refetch()} />
</>
);
}| Method | Description |
| ----------- | ----------------------------------------------------- |
| refetch() | Triggers a new fetch, showing the loading state again |
Theming
Built-in Themes
Two themes are available out of the box:
// Light theme (default)
<MantisRecommender theme="light" ... />
// Dark theme
<MantisRecommender theme="dark" ... />Custom Theme Overrides
Use customTheme to partially override any theme token. Overrides are deep-merged with the selected base theme:
<MantisRecommender
theme="light"
customTheme={{
colors: {
cardBackground: '#F8F9FA',
brandText: '#0066CC',
},
borderRadius: {
card: 12,
},
typography: {
titleFontSize: 18,
},
}}
...
/>Theme Structure
interface MantisTheme {
colors: {
placeholderBackground: string;
titleText: string;
brandText: string;
brandColor: string;
cardBackground: string;
navigationButtonBackground: string;
navigationButtonIcon: string;
navigationButtonDisabledBackground: string;
navigationButtonDisabledIcon: string;
emptyStateText: string;
emptyStateBackground: string;
loadingIndicator: string;
loadingBackground: string;
errorText: string;
errorBackground: string;
};
typography: {
titleFontSize: number;
brandLabelFontSize: number;
navigationIconFontSize: number;
emptyStateTextFontSize: number;
};
spacing: {
containerPadding: number;
contentGap: number;
};
borderRadius: {
card: number;
navigationButton: number;
};
}Using the Theme Context Directly
For advanced use cases, access the resolved theme in your own components:
import { MantisThemeProvider, useMantisTheme } from 'mantis-recommender-react-native';
function CustomOverlay() {
const theme = useMantisTheme();
return <View style={{ backgroundColor: theme.colors.cardBackground }} />;
}
// Wrap with the provider
<MantisThemeProvider themeName="dark" customTheme={myOverrides}>
<CustomOverlay />
</MantisThemeProvider>;Tracking Integration
Event Types
The trackingProvider callback receives a discriminated union of events:
| Event Type | Payload Fields | When Fired |
| --------------- | ---------------------------------------------- | ------------------------------- |
| dataRequested | componentId, timestamp | Fetch begins |
| dataProcessed | componentId, timestamp, data | Fetch succeeds |
| rendered | componentId, timestamp | Items render for the first time |
| impression | componentId, timestamp, item, position | Card becomes 50%+ visible |
| itemPress | componentId, timestamp, item, position | Card is tapped |
| error | componentId, timestamp, error | Fetch fails |
Example: Logging All Events
<MantisRecommender
apiUrl="https://claw.mantis-intelligence.com"
componentId="mantis-ui-widget-1"
url="https://www.mirror.co.uk"
trackingProvider={(event) => {
console.log(`[${event.eventType}]`, event);
}}
onItemPress={(url) => Linking.openURL(url)}
/>Secure Server-Side Tracking
Enable secure tracking to send events to the Mantis secure tracking API:
<MantisRecommender
secureEnabled={true}
secureApiUrl="https://secure.mantis-intelligence.com"
customerId="my-customer-id"
domain="mirror.co.uk"
...
/>Environment Configuration
Recommendations API
| Environment | URL |
| ----------- | -------------------------------------- |
| Production | https://claw.mantis-intelligence.com |
Pass the appropriate URL via the apiUrl prop. The library appends /recommender/agnostic automatically.
Secure Tracking API
| Environment | URL |
| ----------- | ---------------------------------------- |
| Production | https://secure.mantis-intelligence.com |
| QA | https://qa-secure.mantis-dev-awx.com |
| Dev | https://dev-secure.mantis-dev-awx.com |
Pass the appropriate URL via the secureApiUrl prop. Defaults to production if omitted.
Component Layout
The MantisRecommender renders with a header/main/footer structure:
- Header — Title (uppercase, left-aligned) + "Powered by" Mantis logo (right-aligned, theme-aware)
- Main — The active content state (see below)
- Footer — Reserved for future use
Component States
The main section handles four states automatically:
- Loading — Shows a themed
LoadingSpinnerwhile fetching - Success — Renders a horizontal
RecommendationCarouselwith snap-to-page scrolling and navigation buttons - Empty — Shows a themed
EmptyStatewhen the API returns zero items - Error — Shows a themed
ErrorStatewith the error message
Network Behavior
- Timeout: 10 seconds per request
- Retries: Up to 2 retries on non-404 failures
- Backoff: 1s, then 2s between retries
- 404 responses are treated as errors (no retry)
Example App
See the example/ directory for a working Expo app that demonstrates all features including theme switching, event logging, and error states.
Prerequisites
- Node.js 22 LTS (recommended for Expo compatibility)
- Xcode (for iOS simulator) or a physical device with Expo Go
Running the Example
cd example
npm install
npx expo start --clearThen press w to open in the browser, or i for iOS simulator.
The example app imports the library source directly from ../src via Metro's watchFolders, so any changes to the library are picked up automatically — no rebuild or sync step needed.
Building & Publishing
Build
npm run buildCompiles TypeScript source from src/ to CommonJS in dist/ with type declarations.
Publish
npm publishThe prepublishOnly script runs the build automatically before publishing.
Package Contents
The published package includes only dist/ and README.md (~16 kB).
Development
# Install dependencies
npm install
# Build the library
npm run build
# Run tests (requires Node.js 24+)
npm run test:unit
# Run tests with coverage
npm run test:unit:coverage
# Lint & format check
npm run lint:check
# Auto-fix lint & formatting
npm run lint:fixNode.js Version Requirements
| Task | Node.js Version | | ------------------ | --------------- | | Unit tests (Jest) | 24+ | | Example app (Expo) | 22 LTS | | Build & publish | 22+ |
License
MIT — see LICENSE
