npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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-native

Peer Dependencies

Ensure your project has the following peer dependencies installed:

npm install react react-native

Quick 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:

  1. Loading — Shows a themed LoadingSpinner while fetching
  2. Success — Renders a horizontal RecommendationCarousel with snap-to-page scrolling and navigation buttons
  3. Empty — Shows a themed EmptyState when the API returns zero items
  4. Error — Shows a themed ErrorState with 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 --clear

Then 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 build

Compiles TypeScript source from src/ to CommonJS in dist/ with type declarations.

Publish

npm publish

The 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:fix

Node.js Version Requirements

| Task | Node.js Version | | ------------------ | --------------- | | Unit tests (Jest) | 24+ | | Example app (Expo) | 22 LTS | | Build & publish | 22+ |

License

MIT — see LICENSE