UNPKG

@cmscure/react-native-cmscure-sdk

Version:

React Native SDK for CMSCure. Manage UI content, styles, and data stores in real-time.

385 lines (264 loc) 12.4 kB
# React Native CMSCure SDK [![NPM Version](https://img.shields.io/npm/v/@cmscure/react-native-cmscure-sdk.svg)](https://www.npmjs.com/package/@cmscure/react-native-cmscure-sdk) [![License](https://img.shields.io/npm/l/@cmscure/react-native-cmscure-sdk.svg)](https://github.com/cmscure/react-native-cmscure-sdk/blob/main/LICENSE) The official React Native SDK for [CMSCure](https://cmscure.com) — deliver translations, colors, images, and structured data to your React Native app with real-time updates out of the box. ## Features | Feature | Details | |---|---| | **Live Content** | Translations, colors, global images, and data stores | | **Real-time Updates** | Content updates automatically via WebSockets — no polling | | **Hooks-based API** | Reactive hooks (`useCureString`, `useCureColor`, `useCureImage`, `useCureDataStore`, `useCureLanguage`) | | **Data Stores** | Typed access via `.string()`, `.double()`, `.int()`, `.bool()`, `.ctaURL` convenience accessors | | **RTL / LTR Support** | `LanguageDirection` utility with automatic detection for 11+ RTL languages | | **Language Display** | `CureLanguageDisplay` with flag emojis and display names for 80+ languages | | **Native Performance** | Core logic runs on Swift (iOS) and Kotlin (Android) for optimal performance | | **Image Caching** | Built-in caching powered by Kingfisher (iOS) and Coil (Android) | | **Cross-platform API** | Naming conventions align with the native iOS and Android SDKs | ## Requirements | Requirement | Minimum | |---|---| | React Native | 0.71+ | | iOS Target | 14.0+ | | Android API | 24+ | --- ## Installation ### Step 1: Add the Package ```bash npm install @cmscure/react-native-cmscure-sdk # --- or --- yarn add @cmscure/react-native-cmscure-sdk ``` ### Step 2: iOS Configuration (Required) Because the SDK uses native Swift libraries (Kingfisher, Socket.IO), you must enable framework support in your `ios/Podfile`. #### 2.1 — Modify `Podfile` Open your `ios/Podfile` and add `use_frameworks! :linkage => :static` inside your main app target block. This is a **mandatory** step. ```ruby # In your ios/Podfile target 'YourAppName' do # Add this line. It is required for Swift-based pods to work correctly. use_frameworks! :linkage => :static config = use_native_modules! # ... rest of your Podfile configuration end ``` #### 2.2 — Create a Bridging Header (If your app uses Swift) If your project's `AppDelegate` is a `.swift` file, you need a bridging header to make React's Objective-C code available to it. If you already have a file named `YourAppName-Bridging-Header.h`, you can skip to adding the import. **To create one:** 1. Open your project's `.xcworkspace` in Xcode. 2. Go to **File → New → File…**. 3. Choose **Swift File** and click Next. Name it `Dummy.swift` (you can delete it later). 4. When Xcode asks **"Would you like to configure an Objective-C bridging header?"**, click **"Create Bridging Header"**. 5. Xcode will create a file named `YourAppName-Bridging-Header.h`. Open it and add the following import: ```c // In YourAppName-Bridging-Header.h #import <React/RCTBridge.h> ``` 6. You can now delete the `Dummy.swift` file. #### 2.3 — Install Pods ```bash cd ios pod install cd .. ``` ### Step 3: Android Configuration #### 3.1 — Set Minimum SDK Version The CMSCure SDK requires a minimum Android API level of 24. 1. Open your project's `android/build.gradle` file. 2. Ensure the `minSdkVersion` is set to `24` or higher. ```groovy // In android/build.gradle android { defaultConfig { minSdkVersion = 24 // <-- This must be at least 24 } } ``` #### 3.2 — Install Dependencies The library is auto-linked. No further steps are usually required. --- ## Quick Start ### 1. Create Content in the CMSCure Dashboard Create a new project and add the following content. These keys and values are used by the two example files in the [`examples/`](examples/) folder ([Basic](examples/BasicExample.js) and [Advanced](examples/AdvancedExample.js)), so adding them lets you run the examples immediately: | Type | Screen / Store | Key | Sample Value | |------|---------------|-----|-------------| | Translation | `home_screen` | `welcome_title` | Welcome! | | Translation | `home_screen` | `welcome_subtitle` | Manage content, your way. | | Translation | `home_screen` | `cta_button` | Get Started | | Color | — | `primary_color` | #007AFF | | Color | — | `accent_color` | #FF9500 | | Color | — | `background_color` | #F2F2F7 | | Image | — | `app_logo` | *(upload your logo)* | | Image | — | `hero_banner` | *(upload a banner)* | | Data Store | `feature_products` | — | Store Name: **Feature Products**, Fields: `title` (String), `price` (Number), `image_url` (String) | ### 2. Configure with CMSCureProvider Wrap your app in `CMSCureProvider` — it initializes the SDK, syncs colors and images, and provides context to all hooks. ```javascript import { CMSCureProvider } from '@cmscure/react-native-cmscure-sdk'; const cmsConfig = { projectId: 'YOUR_PROJECT_ID', // ← replace apiKey: 'YOUR_API_KEY', // ← replace projectSecret: 'YOUR_PROJECT_SECRET', // ← replace }; export default function App() { return ( <CMSCureProvider config={cmsConfig}> <HomeScreen /> </CMSCureProvider> ); } ``` > **Replace** `YOUR_PROJECT_ID`, `YOUR_API_KEY`, and `YOUR_PROJECT_SECRET` with the credentials from your CMSCure dashboard. --- ## Hooks All hooks must be used inside a `CMSCureProvider`. They automatically re-render when CMS content changes in real time. ### `useCureString` Reactive CMS translation string. ```javascript import { useCureString } from '@cmscure/react-native-cmscure-sdk'; const title = useCureString('welcome_title', 'home_screen', 'Welcome!'); // key tab default ``` ### `useCureColor` Reactive CMS color hex string. ```javascript import { useCureColor } from '@cmscure/react-native-cmscure-sdk'; const primaryColor = useCureColor('primary_color', '#007AFF'); // key default ``` ### `useCureImage` Reactive CMS image URL. Pass `tab` for translation-based images, omit for global images. ```javascript import { useCureImage, CureSDKImage } from '@cmscure/react-native-cmscure-sdk'; const heroUrl = useCureImage('hero_banner'); // <CureSDKImage url={heroUrl} style={{ width: '100%', height: 200 }} resizeMode="cover" /> ``` ### `useCureDataStore` Reactive CMS data store. Returns `{ items, isLoading }` where each item has typed convenience accessors. ```javascript import { useCureDataStore } from '@cmscure/react-native-cmscure-sdk'; const { items: products, isLoading } = useCureDataStore('feature_products'); products.forEach((item) => { const name = item.string('title'); // localized string const price = item.double('price'); // number or null const cta = item.ctaURL; // CTA URL from "cta_url" field }); ``` ### `useCureLanguage` Returns the current language code, RTL flag, flag emoji, and display name. Re-renders on language changes. ```javascript import { useCureLanguage } from '@cmscure/react-native-cmscure-sdk'; const lang = useCureLanguage(); // lang.code → "ar" // lang.isRTL → true // lang.flag → "🇸🇦" // lang.displayName → "Arabic" ``` --- ## Core API The `Cure` object provides imperative access to all SDK functions. Use it outside of hooks or for manual control. ```javascript import { Cure } from '@cmscure/react-native-cmscure-sdk'; ``` ### Translations ```javascript const title = await Cure.translation('welcome_title', 'home_screen'); ``` ### Colors ```javascript const hex = await Cure.colorValue('primary_color'); // "#007AFF" ``` ### Images ```javascript const url = await Cure.imageURL('hero_banner'); ``` ### Data Stores ```javascript const items = await Cure.getStoreItems('feature_products'); items.forEach((item) => { console.log(item.string('title')); // localized string console.log(item.double('price')); // number console.log(item.bool('is_active')); // boolean console.log(item.ctaURL); // CTA URL or null }); // Or sync from server first: const freshItems = await Cure.syncStore('feature_products'); ``` ### Manual Sync ```javascript await Cure.sync('home_screen'); ``` --- ## Language Management ```javascript // Set language — all hooks re-render automatically await Cure.setLanguage('fr'); // Get current language const code = await Cure.getLanguage(); // "fr" // List available languages const languages = await Cure.availableLanguages(); // ["en", "fr", "ar"] ``` ### Language Direction (RTL / LTR) The SDK includes a pure-JS `LanguageDirection` utility for layout handling: ```javascript import { LanguageDirection } from '@cmscure/react-native-cmscure-sdk'; LanguageDirection.direction('ar'); // "RTL" LanguageDirection.direction('en'); // "LTR" LanguageDirection.isRTL('he'); // true ``` Supported RTL languages: `ar`, `he`, `fa`, `ur`, `ps`, `sd`, `ku`, `yi`, `ckb`, `dv`, `ug`. ### Language Display Helpers Built-in flag emojis and display names for 80+ languages. No need to maintain your own mappings: ```javascript import { CureLanguageDisplay } from '@cmscure/react-native-cmscure-sdk'; CureLanguageDisplay.flag('ar'); // "🇸🇦" CureLanguageDisplay.flag('pt-br'); // "🇧🇷" CureLanguageDisplay.displayName('fr'); // "French" CureLanguageDisplay.displayName('zh-tw'); // "Chinese (Traditional)" ``` --- ## Components ### `<CureSDKImage />` Renders a CMS-managed image from a URL. Returns `null` when the URL is falsy. Accepts all standard React Native `<Image>` props. ```javascript import { CureSDKImage, useCureImage } from '@cmscure/react-native-cmscure-sdk'; const logoUrl = useCureImage('app_logo'); <CureSDKImage url={logoUrl} style={{ width: 60, height: 60 }} resizeMode="contain" /> ``` --- ## Constants ```javascript import { CMSCureConstants } from '@cmscure/react-native-cmscure-sdk'; CMSCureConstants.ALL_SCREENS_UPDATED // "__ALL_SCREENS_UPDATED__" CMSCureConstants.COLORS_UPDATED // "__colors__" CMSCureConstants.IMAGES_UPDATED // "__images__" ``` --- ## iOS / Android / React Native API Parity | iOS | Android | React Native | Notes | |---|---|---|---| | `Cure.shared.configure(...)` | `Cure.configure(...)` | `Cure.configure({...})` | Provider handles this | | `CureString(key, tab:)` | `rememberCureString(key, tab)` | `useCureString(key, tab)` | Reactive hook | | `CureColor(key)` | `rememberCureColor(key)` | `useCureColor(key)` | Returns hex string | | `Cure.shared.imageURL(forKey:)` | `Cure.imageURL(forKey:)` | `useCureImage(key)` | Returns URL string | | `CureDataStore(apiIdentifier:)` | `cureDataStore(id)` | `useCureDataStore(id)` | `{ items, isLoading }` | | `item.string("key")` | `item.string("key")` | `item.string("key")` | Same typed accessors | | `item.double("key")` | `item.double("key")` | `item.double("key")` | Same typed accessors | | `item.ctaURL` | `item.ctaURL` | `item.ctaURL` | Same property | | `CureLanguageDisplay.flag(for:)` | `CureLanguageDisplay.flag(code)` | `CureLanguageDisplay.flag(code)` | Flag emoji | | `LanguageDirection.direction(for:)` | `LanguageDirection.direction(code)` | `LanguageDirection.direction(code)` | `"RTL"` / `"LTR"` | --- ## Examples Complete working examples are in the [`examples/`](examples/) folder: | Example | Description | |---------|-------------| | [`BasicExample.js`](examples/BasicExample.js) | Full app with `CMSCureProvider`, all hooks, data store with typed accessors, and language picker with RTL badge | | [`AdvancedExample.js`](examples/AdvancedExample.js) | Imperative `Cure.*` API, manual sync, real-time event listeners, and standalone utilities | Both examples use the keys from the Quick Start table above. --- ## Troubleshooting - **Hooks not working?** Make sure your component is inside `<CMSCureProvider>`. - **iOS build fails?** Ensure `use_frameworks! :linkage => :static` is in your `Podfile` and you ran `pod install`. - **Android build fails?** Ensure `minSdkVersion` is at least `24`. - **Content not updating?** Check that `enableAutoRealTimeUpdates` is `true` (default) in your config. ## License MIT — see [LICENSE](LICENSE).