⚙️ ZezoOTT API Setup (React Native with Expo Prebuild)
This guide explains how to configure and use the ZezoOTT API Client in a React Native project using Expo Prebuild, secure token storage, environment variables, interceptors, and auto-logout logic.
📦 Required Dependencies
Install all required packages:
yarn
yarn add @zezosoft/zezo-ott-api-client react-native-mmkv react-native-device-info react-native-dotenv
🔐 Token Storage
import { MMKV } from "react-native-mmkv";
const storage = new MMKV();
export const tokenStorage = {
set: (key: string, value: string) => storage.set(key, value),
getString: (key: string) => storage.getString(key) || undefined,
delete: (key: string) => storage.delete(key),
clearAll: () => storage.clearAll(),
};
🌱 Environment Variable Setup
Create a .env
file in the project root:
API_BASE_URL=https://api.zezosoft.com
CRYPTOJS_KEY_APP=xyz...
🔧 Configure Babel
module.exports = {
presets: ["module:metro-react-native-babel-preset"],
plugins: [
[
"module:react-native-dotenv",
{
moduleName: "@env",
path: ".env",
blocklist: null,
allowlist: null,
safe: false,
allowUndefined: true,
},
],
],
};
Then use variables like:
import { API_BASE_URL } from "@env";
⚠️ Important: Babel config is only for React Native CLI users.
If you’re using Expo, skip this and follow Expo Environment Variable Setup
🧾 Declare .env Types
To enable TypeScript support for .env
variables:
declare module "@env" {
export const ENVIRONMENT: "development" | "production" | "staging";
export const API_BASE_URL: string;
export const BASE_URL: string;
export const CRYPTOJS_KEY_APP: string;
export const WEBSITE_URL: string;
export const EIGHTEEN_PLUS_ALERT: "true" | "false";
export const RECAPTCHA_ENABLED: "true" | "false";
export const RECAPTCHA_SITE_KEY: string;
export const RECAPTCHA_BASE_URL: string;
export const IAPHUB_APP_ID: string;
export const IAPHUB_APP_API_KEY: string;
export const IS_PAYMENT_INITIATED_ENABLED: "true" | "false";
export const APP_UPDATE_ENABLED: "true" | "false";
export const SPLASH_SCREEN: string | undefined | "none";
export const SPLASH_SCREEN_BACKGROUND: string | undefined | "none";
export const SPLASH_SCREEN_TIMEOUT: string | undefined | "none";
export const LOGO: string | undefined | "none";
export const DEFAULT_PROFILE: string | undefined | "none";
export const SPACES_BASE_URL: string | undefined | "none";
}
✅ This setup is tested and compatible with Expo Prebuild (npx expo prebuild
).
🧭 Navigation Utility
🧩 Routes Enum
export enum Route {
LoginWithEmail = "LoginWithEmail",
Home = "Home",
}
🍪 Extract Tokens from Cookie Headers
export type Headers = {
["set-cookie"]: string[];
};
export interface Tokens {
accessTokenDeprecated: string | null;
accessToken: string | null;
refreshToken: string | null;
}
export const getTokensFromHeader = (headers: Headers): Tokens => {
let accessTokenDeprecated: string | null = null;
let accessToken: string | null = null;
let refreshToken: string | null = null;
const cookies = headers["set-cookie"] || [];
const keyValuePairArray = cookies?.[0]?.split(", ");
if (!keyValuePairArray) {
return { accessTokenDeprecated, accessToken, refreshToken };
}
keyValuePairArray.forEach((pair) => {
const [key, value] = pair.split("=");
const parsedValue = value?.split(";")[0];
if (key === "accessToken") {
accessToken = parsedValue;
}
if (key === "refreshToken") {
refreshToken = parsedValue;
}
if (key === "accessTokenDeprecated") {
accessTokenDeprecated = parsedValue;
}
});
return { accessTokenDeprecated, accessToken, refreshToken };
};
⚙️ API Client Setup
import { API_BASE_URL } from "@env";
import { Route } from "@navigation/routes";
import { tokenStorage } from "@ZezoOtt/store/storage";
import { getTokensFromHeader, Headers } from "@ZezoOtt/utils";
import { resetAndNavigate } from "@ZezoOtt/utils/NavigationUtil";
import { ZezoOTT } from "@zezosoft/zezo-ott-api-client";
import DeviceInfo from "react-native-device-info";
let zezoOtt: ZezoOTT;
export type IAPIError = {
response?: {
status?: number;
data?: {
error?: { message?: string };
message?: string;
};
};
};
export const getZezoOtt = () => {
if (!zezoOtt) {
zezoOtt = new ZezoOTT({
baseUrl: API_BASE_URL,
withCredentials: true,
interceptors: {
request: async (config) => {
const accessToken = tokenStorage.getString("accessToken");
const refreshToken = tokenStorage.getString("refreshToken");
const authorizationDeprecated = tokenStorage.getString(
"accessTokenDeprecated"
);
const [deviceIdResult, deviceNameResult] = await Promise.allSettled([
DeviceInfo.getUniqueId(),
DeviceInfo.getDeviceName(),
]);
const deviceId =
deviceIdResult.status === "fulfilled" ? deviceIdResult.value : "";
const deviceName =
deviceNameResult.status === "fulfilled"
? deviceNameResult.value
: "";
config.headers = {
...config.headers,
Accept: "application/json",
"Content-Type": "application/json",
"x-user-device-id": deviceId,
"x-user-browser": deviceName,
"x-user-os": deviceName,
...(accessToken && { Authorization: `Bearer ${accessToken}` }),
...(refreshToken && { RefreshToken: refreshToken }),
...(authorizationDeprecated && {
authorizationDeprecated: `Bearer ${authorizationDeprecated}`,
}),
};
return config;
},
response: async (response) => {
const tokens = getTokensFromHeader(response.headers as Headers);
if (tokens?.accessToken)
tokenStorage.set("accessToken", tokens.accessToken);
if (tokens?.refreshToken)
tokenStorage.set("refreshToken", tokens.refreshToken);
if (tokens?.accessTokenDeprecated)
tokenStorage.set(
"accessTokenDeprecated",
tokens.accessTokenDeprecated
);
return response;
},
responseError: async (error) => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
tokenStorage.clearAll();
resetAndNavigate(Route.LoginWithEmail);
}
return Promise.reject(error);
},
},
});
}
return zezoOtt;
};
📘 See full API client README on GitHub:
Zezo OTT API Client Documentation
🔍 API Usage Example
import { getZezoOtt } from "@ZezoOtt/http/client";
export default function App() {
useEffect(() => {
const fetchCategories = async () => {
try {
const response = await getZezoOtt().categories.get();
console.log("📦 Categories:", response);
} catch (error) {
console.error("❌ Failed to fetch categories:", error);
}
};
fetchCategories();
}, []);
return <></>;
}
✅ Summary
Feature | Included |
---|---|
MMKV Secure Token Storage | ✅ |
Axios Interceptors | ✅ |
401 Auto Logout Redirect | ✅ |
Device Info Headers | ✅ |
TypeScript Error Handling | ✅ |
.env Config Support | ✅ |
Expo Prebuild Compatible | ✅ |
Need help with refresh token rotation
, middleware
, or secure onboarding
?
Ping us anytime ✅
✍️ Created by Naresh Dhamu – Powered by ZezoSoft