> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mazeedplus.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mobile Ad Integration

> React Native + WebView integration for displaying ad placements in mobile applications

## Overview

This guide covers integrating Mazeed+ placement API into React Native mobile applications using WebView for rendering ad placements.

**Integration Method:** Direct API call from mobile application

## Mazeed+ Credentials

You will receive:

* **Publishable API Key** – For `x-publishable-api-key` header
* **Placement ID** – For `identifier` field

### API Endpoint

```
POST https://api.mazeedplus.com/select-placement
```

### Response Formats

#### JSON Response (Default)

When requesting with `Accept: application/json` (default):

| Attribute       | Type   | Description                          |
| --------------- | ------ | ------------------------------------ |
| `identifier`    | String | The placement ID requested           |
| `templateName`  | String | Template name                        |
| `template_data` | Object | Structured data for native rendering |

#### HTML Response

When requesting with `Accept: text/html`, the API returns an HTML document directly in the response body.

## Request Attributes

### Required Attributes

| Attribute           | Description                                                  | Required |
| ------------------- | ------------------------------------------------------------ | -------- |
| `identifier`        | Placement ID provided by Mazeed+                             | Yes      |
| `attributes.userId` | Unique identifier for the user                               | Yes      |
| `attributes.mobile` | Mobile number in international format (e.g., `+9665xxxxxxx`) | Yes      |

### Recommended Optional Attributes

| Attribute                    | Description                                | Example                   |
| ---------------------------- | ------------------------------------------ | ------------------------- |
| `attributes.country`         | Country code                               | `"sa"`                    |
| `attributes.currency`        | Currency code                              | `"sar"`                   |
| `attributes.firstname`       | User's first name                          | `"Ahmed"`                 |
| `attributes.lastname`        | User's last name                           | `"Al-Rashid"`             |
| `attributes.gender`          | User's gender                              | `"male"` or `"female"`    |
| `attributes.age`             | User's age in years                        | `28`                      |
| `attributes.interests`       | Array of user interest strings             | `["sports", "tech"]`      |
| `attributes.confirmationref` | Order or transaction reference             | `"ORD-12345"`             |
| `attributes.paymenttype`     | Payment method used                        | `"credit_card"`, `"cash"` |
| `attributes.cartItems`       | JSON string of cart items                  | `"[{\"id\":\"123\"}]"`    |
| `attributes.q`               | Search query for finding relevant products | `"كولومبي قهوه"`          |

## React Native Implementation

### Configuration

```typescript theme={null}
// config/mazeed.ts
export const MAZEED_PUBLISHABLE_KEY = "pk_live_...";
export const MAZEED_PLACEMENT_ID = "checkout_success";
```

### API Service

```typescript theme={null}
// api/mazeed.ts

import { MAZEED_PUBLISHABLE_KEY, MAZEED_PLACEMENT_ID } from "../config/mazeed";

export async function fetchMazeedPlacement(user: {
  userId: string;
  mobile: string;
  country?: string;
  currency?: string;
  firstname?: string;
  lastname?: string;
}) {
  const res = await fetch("https://api.mazeedplus.com/select-placement", {
    method: "POST",
    headers: {
      "x-publishable-api-key": MAZEED_PUBLISHABLE_KEY,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      identifier: MAZEED_PLACEMENT_ID,
      attributes: {
        userId: user.userId,
        mobile: user.mobile,
        country: user.country,
        currency: user.currency,
        firstname: user.firstname,
        lastname: user.lastname
      }
    })
  });

  if (!res.ok) {
    return { html: "", css: "" };
  }

  const data = await res.json();
  return {
    html: data.html as string | undefined,
    css: data.css as string | undefined
  };
}
```

## WebView Renderer

### Install Dependencies

```bash theme={null}
npm install react-native-webview
```

### WebView Component

```typescript theme={null}
// components/MazeedPlacementWebView.tsx

import React, { useMemo } from "react";
import { WebView } from "react-native-webview";

type Props = {
  html: string;  // Full HTML document from API
};

export const MazeedPlacementWebView: React.FC<Props> = ({ html }) => {
  if (!html) return null;

  return (
    <WebView
      originWhitelist={["*"]}
      source={{ html }}
    />
  );
};
```

## Usage Example

```typescript theme={null}
// screens/PlacementScreen.tsx

import React, { useEffect, useState } from "react";
import { View, ActivityIndicator } from "react-native";
import { fetchMazeedPlacement } from "../api/mazeed";
import { MazeedPlacementWebView } from "../components/MazeedPlacementWebView";

export const PlacementScreen = () => {
  const [placement, setPlacement] = useState<{ html?: string; css?: string }>();

  useEffect(() => {
    (async () => {
      const result = await fetchMazeedPlacement({
        userId: "user_123",
        mobile: "+966512345678",
        country: "sa",
        currency: "sar"
      });

      setPlacement(result);
    })();
  }, []);

  if (!placement) return <ActivityIndicator />;

  if (!placement.html) return null;

  return (
    <View style={{ flex: 1 }}>
      <MazeedPlacementWebView html={placement.html} />
    </View>
  );
};
```

## Integration Summary

**Quick Checklist:**

* Get Publishable API Key and Placement ID from Mazeed+
* Install `react-native-webview`
* Configure credentials
* Implement API service
* Create WebView component
* Integrate into screen

**Data Flow:**

1. Call API with: `identifier`, `userId`, `mobile`
2. Receive: `html` and `css`
3. Render in WebView

## Performance: Preloading WebView

**Recommendation:** Preload WebView before showing to users.

```typescript theme={null}
// components/MazeedPlacementWebView.tsx (Enhanced)

import React, { useMemo, useState } from "react";
import { WebView } from "react-native-webview";
import { View, ActivityIndicator, StyleSheet } from "react-native";

type Props = {
  html: string;  // Full HTML document from API
};

export const MazeedPlacementWebView: React.FC<Props> = ({ html }) => {
  const [isLoaded, setIsLoaded] = useState(false);

  if (!html) return null;

  return (
    <View style={styles.container}>
      {!isLoaded && (
        <View style={styles.loaderContainer}>
          <ActivityIndicator size="large" color="#0000ff" />
        </View>
      )}
      <WebView
        originWhitelist={["*"]}
        source={{ html }}
        onLoadEnd={() => setIsLoaded(true)}
        style={[styles.webview, !isLoaded && styles.hidden]}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  loaderContainer: {
    ...StyleSheet.absoluteFillObject,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#ffffff",
  },
  webview: {
    flex: 1,
  },
  hidden: {
    opacity: 0,
  },
});
```

### Best Practices

* Hide WebView until content is fully rendered
* Use `onLoadEnd` callback
* Don't show empty WebView while loading

## Mobile Number Format

**Correct Format:**

```typescript theme={null}
mobile: "+966512345678"
```

**Incorrect Format:**

```typescript theme={null}
mobile: "0512345678"  // Missing country code
```
