# @taboola/react-native-plugin-4x

🚀 **The official Taboola React Native Plugin** for integrating native recommendations and content discovery into your React Native applications.

[![npm version](https://badge.fury.io/js/@taboola%2Freact-native-plugin-4x.svg)](https://badge.fury.io/js/@taboola%2Freact-native-plugin-4x)
[![React Native](https://img.shields.io/badge/React%20Native-0.70+-blue.svg)](https://reactnative.dev/)
[![Platform - Android](https://img.shields.io/badge/platform-Android-green.svg)](http://developer.android.com/index.html)
[![Platform - iOS](https://img.shields.io/badge/platform-iOS-blue.svg)](https://developer.apple.com/ios/)

## 🎯 What's New in 4.x

- ✅ **Full React Native New Architecture support** (TurboModules & Fabric)
- ✅ **Separated data fetching and UI rendering** for better control
- ✅ **Hook-based API** with `useCreateUnit`
- ✅ **Improved TypeScript support** and type safety
- ✅ **Better memory management** with explicit cleanup
- ✅ **Multiple units per screen** support
- ✅ **Enhanced GDPR/CCPA compliance** controls

## 📦 Installation

```bash
npm install @taboola/react-native-plugin-4x
```

### Android Additional Setup

In your project's Android folder, edit `android/settings.gradle`:

```gradle
dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
  repositories {
    google()
    mavenCentral()
    maven {
      // Taboola:
      url 'https://taboolapublic.jfrog.io/artifactory/mobile-release'
    }
  }
}
```

### iOS Additional Setup

```bash
cd ios && pod install
```

> **Note for Apple Silicon users**: If you are using an Apple silicon machine, add an exclusion for `arm64` to your Podfile (as well as your project settings) to prevent potential problems with the iPhone simulator.

## ⚡ Quick Start

### 1. Initialize Taboola

```jsx
// Initialize in your index.js or index.ts (application entry-point)
import { Taboola } from '@taboola/react-native-plugin-4x';

// Initialize as soon as possible
Taboola.init('your-publisher-name');

// Your app registration
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);
```

### 2. Create a Feed Unit

```jsx
import React from 'react';
import { ActivityIndicator, Text } from 'react-native';
import {
  useCreateUnit,
  TBLClassicPage,
  TBLClassicUnit,
  TBLPlacementType
} from '@taboola/react-native-plugin-4x';

const TaboolaFeedScreen = () => {
  // Create page instance with separate parameters
  const classicPage = new TBLClassicPage(
    'https://example.com/article',
    'article'
  );

  // Create unit with complete listener interface
  const { tblClassicUnitController } = useCreateUnit({
    tblClassicPage: classicPage,
    placement: 'Mid Article',
    mode: 'alternating-widget-1',
    placementType: TBLPlacementType.FEED,
    tblClassicListener: {
      onItemClick: (placementName, itemId, clickUrl, isOrganic, customData) => {
        console.log('Item clicked:', clickUrl);
      },
      onTaboolaWidgetOnTop: () => {
        console.log('Widget scrolled to top');
      },
      onAdReceiveSuccess: () => {
        console.log('Ads loaded successfully');
      },
      onAdReceiveFail: (error) => {
        console.log('Failed to load ads:', error);
      },
      onResize: (height) => {
        console.log(`Widget resized to ${height}px`);
      },
      onUpdateContentCompleted: () => {
        console.log('Content update completed');
      },
      onEvent: (actionType, data) => {
        console.log('Custom event:', actionType, data);
      }
    }
  });

  return (
    <TBLClassicUnit
      tblClassicPage={classicPage}
      tblClassicUnitController={tblClassicUnitController}
    />
  );
};
```



## 🛠️ Key Components & Hooks

| Component/Hook | Purpose |
|---|---|
| `useCreateUnit` | Hook for creating Taboola unit controllers |
| `TBLClassicUnit` | React component that renders Taboola content |
| `TBLClassicPage` | Page-level configuration and management |
| `Taboola.init()` | Initialize the SDK with your credentials |

## 🎛️ Configuration Options

### Placement Types
```jsx
import { TBLPlacementType } from '@taboola/react-native-plugin-4x';

TBLPlacementType.FEED        // Endless scrolling feed
TBLPlacementType.PAGE_MIDDLE // Widget within content
TBLPlacementType.PAGE_BOTTOM // Widget at page bottom
```

### Complete Event Handling
```jsx
const tblClassicListener = {
  onItemClick: (placementName, itemId, clickUrl, isOrganic, customData) => {},
  onTaboolaWidgetOnTop: () => {},
  onAdReceiveSuccess: () => {},
  onAdReceiveFail: (error) => {},
  onResize: (height) => {},
  onUpdateContentCompleted: () => {},
  onEvent: (actionType, data) => {},
};
```

### Extra Properties
```jsx
import { Taboola } from '@taboola/react-native-plugin-4x';


// Set Taboola-global-level
Taboola.setGlobalExtraProperties({
  'custom-property': 'value',
  'user-segment': 'premium'
})

// Create page first, then set extra properties
const classicPage = new TBLClassicPage(
  'https://example.com',
  'article'
);

// Set page-level extra properties
classicPage.setPageExtraProperties({
  'custom-property': 'value',
  'user-segment': 'premium'
});

// Set unit-level extra properties (after unit creation)
tblClassicUnitController?.setUnitExtraProperties({
  'unit-specific': 'property'
});
```

## 🔧 Advanced Features

### Memory Management
```jsx
import { useEffect } from 'react';

const TaboolaScreen = () => {
  const classicPage = new TBLClassicPage(pageUrl, pageType);
  const { tblClassicUnitController } = useCreateUnit({...});

  // Cleanup when component unmounts
  useEffect(() => {
    return () => {
      Taboola.removeClassicPage(classicPage);
    };
  }, [classicPage]);

  return (
    <TBLClassicUnit
      tblClassicPage={classicPage}
      tblClassicUnitController={tblClassicUnitController}
    />
  );
};
```

### Debugging

### Log Levels

Taboola SDK provides different log levels to help you debug integration issues. Set the appropriate log level based on your needs:

```jsx
import { Taboola, TBLLogLevel } from '@taboola/react-native-plugin-4x';

// Set log level for debugging (should be done after Taboola.init())
Taboola.setLogLevel(TBLLogLevel.DEBUG);
```

### Common Debugging Scenarios

```jsx
// Example: Full debugging setup
import { Taboola, TBLLogLevel } from '@taboola/react-native-plugin-4x';

// Initialize Taboola
Taboola.init('your-publisher-name');

// Enable detailed logging for development
Taboola.setLogLevel(TBLLogLevel.DEBUG);

```

### Multiple Units
```jsx
const FeedWithMultipleUnits = () => {
  const classicPage = new TBLClassicPage(pageUrl, pageType);

  const { tblClassicUnitController: widgetUnit } = useCreateUnit({
    tblClassicPage: classicPage,
    placement: 'Mid Article',
    mode: 'alternating-widget-1',
    placementType: TBLPlacementType.PAGE_MIDDLE,
    tblClassicListener: { /* ... */ }
  });

  const { tblClassicUnitController: feedUnit } = useCreateUnit({
    tblClassicPage: classicPage,
    placement: 'Bottom Feed',
    mode: 'thumbs-feed-01',
    placementType: TBLPlacementType.FEED,
    tblClassicListener: { /* ... */ }
  });

  return (
    <ScrollView>
        <TBLClassicUnit
          tblClassicPage={classicPage}
          tblClassicUnitController={widgetUnit}
        />
        <TBLClassicUnit
          tblClassicPage={classicPage}
          tblClassicUnitController={feedUnit}
        />
    </ScrollView>
  );
};
```

### Dark Mode Support
```jsx

Taboola.setGlobalExtraProperties({ 'darkMode': 'true' });

classicPage.setPageExtraProperties({ 'darkMode': 'true' });

// For dynamic dark-mode use this level, right after tblClassicUnitController?.setUnitExtraProperties({
// 'darkMode': 'true'
// });
// call tblClassicUnitController.fetchContent()
tblClassicUnitController?.setUnitExtraProperties({ 'darkMode': 'true' });


```

### Unit Control Methods
```jsx
const TaboolaControls = ({ tblClassicUnitController, classicPage }) => {
  const handleRefresh = () => {
    tblClassicUnitController?.refresh();
  };

  const handleFetchContent = () => {
    tblClassicUnitController?.fetchContent();
  };

  const handleReset = () => {
    tblClassicUnitController?.reset();
  };

  const handlePageRefresh = () => {
    classicPage.refresh();
  };

  return (
    <View>
      <Button title="Refresh Unit" onPress={handleRefresh} />
      <Button title="Fetch Content" onPress={handleFetchContent} />
      <Button title="Reset Unit" onPress={handleReset} />
      <Button title="Refresh Page" onPress={handlePageRefresh} />
    </View>
  );
};
```

## 📱 Requirements

- **React Native**: 0.79.2+
- **React Native New Architecture**: Fully supported

## 🔗 Links & Resources

- 📚 **[Complete Documentation](https://developers.taboola.com/taboolasdk/docs/react-native-plugin)** - Full integration guide and API reference
- 🎯 **[Sample App](https://github.com/taboola/react-native-examples-4x)** - Complete working examples
- 💬 **[Support Forum](https://sdk.taboola.com/taboolasdk/discuss)** - Get help from the community
- 🔄 **[Migration Guide](https://developers.taboola.com/taboolasdk/docs/react-native-migration)** - Upgrading from 3.x

## 🆘 Support

- **Documentation**: [Taboola Developer Center](https://developers.taboola.com/taboolasdk/docs/react-native-plugin)
- **Issues**: [GitHub Issues](https://github.com/taboola/react-native-examples-4x/issues)
- **Community**: [Support Forum](https://sdk.taboola.com/taboolasdk/discuss)

## 📄 License

MIT © [Taboola](https://www.taboola.com)

---

**Need help getting started?** Check out our [complete integration guide](https://developers.taboola.com/taboolasdk/docs/react-native-plugin) or try the [sample app](https://github.com/taboola/react-native-examples-4x).
