SDK DocumentationRecipesAnnouncementsSupport Forum
AndroidiOSAnnouncementsSupport Forum

Feed via JS


Have you gone through the instructions of Getting started?

  • Make sure that you complete the SDK installation before performing the procedures in this article
  • Feed via JS in-app supports iOS 9.0 and above (deployment target: iOS 9), The maximum supported Base SDK is iOS 13 (recommended), and the Minimum xCode version - 9.2


See our code examples!

On our Github repository, you may find numerousย code examplesย demonstrating the usage of our features.


Stuck? Confused? Use our Support Forum!

If you need quick help in integrating Taboola SDK into your help, you can use our support forum. The forum is monitored continuously by Taboola Support and will respond within 24 business hours.

Step 1: Import Taboola

For CocoaPods, import TaboolaSDK into your bridging header.

#import <TaboolaSDK/TaboolaSDK.h>
import TaboolaSDK

For Carthage, import the framework:

#import <TaboolaFramework/TaboolaFramework.h>
import TaboolaFramework

Step 2: Initialize Taboola

Create a PublisherInfo object and init Taboola

PublisherInfo *publisherInfo = [[PublisherInfo alloc]initWithPublisherId:@"publisherId"];

[Taboola initWithPublisherInfo:publisherInfo];
let publisherInfo = PublisherInfo.init(publisherId: "publisherId")
  • publisherId - Your publisher ID as provided to you by Taboola account manager

Step 3: Register the Webview

Before loading the actual content in your webview, register the webview that is intended to contain the Taboola feed.

Make sure to unregister your webview before it is destroyed.

Register the webview in your ViewController code:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Optional but important for video!
    // To show video ads please add this code
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    [config setAllowsInlineMediaPlayback:YES];
    [config.preferences setJavaScriptCanOpenWindowsAutomatically:YES];
    self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
   // implement the `withDelegate:self` to get events (optional - see step 3)
   [[TaboolaJS sharedInstance] registerWebView:self.webView withDelegate:self];

override func viewDidLoad() {
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        config.preferences.javaScriptCanOpenWindowsAutomatically = true
        webView = WKWebView(frame: view.frame, configuration: config)
        // implement the `with: self` to get events (optional - see step 3)
        TaboolaJS.sharedInstance()?.registerWebView(webView, with: self)
        webView.loadHTMLString(appHtml, baseURL: URL(string: "https:"))



Taboola recommends to register the webview before loading any content to it. If you register the webview after loading it. please refresh its content.

Step 4: Adding HTML/JS tag within the Webview

Your HTML page loaded inside the webview should contain the Taboola mobile JS code. This is to bind with the TaboolaJS native SDK and actually display the feed.

If you are already familiar with the Taboola web JS code, notice that although the Taboola mobile JS code is mostly identical to the Taboola web JS code, there are a few minor modifications to be made.

Place this code in the <head> tag of the webview that will contain the Taboola asset. Make sure you replace the values as described below the code example.

<script type="text/javascript">
     window._taboola = window._taboola || [];
     _taboola.push({page-type:'auto', url:'pass-url-here'});
     !function (e, f, u, i) {
          if (!document.getElementById(i)){
               e.async = 1;
               e.src = u;
      = i;
               f.parentNode.insertBefore(e, f);
  • page-type key - replace the "page-type" key string with the key that represents the type of the page (video, article, photo, search, category, and home). Please use the value given to you by your Taboola account manager
  • page-type value - use auto to assign an automated id to the current page. If you wish to pass your own internal ID for the current page, please pass the value instead of auto. For example: article: your_internal_id
  • pass-url-here: pass the canonical URL (web representation) of the app page - this is needed for Taboola to crawl the page to get contextual and metadata
  • publisher-id: replace it with the publisher ID received from your Taboola account manager

Place this code anywhere in the <body> tag of the webview that will contain the Taboola asset. Make sure you replace the values as described below the code example.

<div id="container-id"></div>
<script type="text/javascript">
     window._taboola = window._taboola || [];
     _taboola.push({mode: 'mode-name',
     	container: 'container-id',
     	placement: 'Placement Name',
     	target_type: 'mix'});

 // Notice - this part is unique to mobile SDK JS integrations!
_taboola["mobile"] = window._taboola["mobile"] || [];
        taboola_view_id:'view id',
  • container-id: use any id for the actual feed container element
  • mode-name: replace it with the mode parameter received from your Taboola account manager
  • Placement Name: use the placement name received from your Taboola account manager
  • taboola_view_id: (optional, but mandatory when using more than one Taboola on the same HTML file) set view id to prevent duplicated between different placements (can use: new Date().getTime()). Make sure to use this value on any Taboola asset located on the same webview
  • publisher-id-goes-here: replace it with the publisher ID received from your Taboola account manager



Do not forget to register your webview with the native TaboolaJS object as described in Step 1

Step 5: Additional Integration Information (Optional)


App developers may choose to implement the TaboolaJSDelegate optional methods didLoadPlacementNamed and didFailToLoadPlacementNamed to receive a notification when a feed has loaded or failed to load.

Implement these methods in the same object which handles the clicks and implements TaboolaJSDelegate.

- (void)webView:(WebView) webView didLoadPlacementNamed:(NSString*) placementName withHeight:(CGFloat)height;
- (void)webView:(WebView) webView didFailToLoadPlacementNamed:(NSString*) placementName withErrorMessage:(NSString*) error;
func webView(_ webView: UIView!, didLoadPlacementNamed placementName: String!, withHeight height: Float!) {
        print("Placement \(String(describing: placementName)) loaded successfully")
    func webView(_ webView: UIView!, didFailToLoadPlacementNamed placementName: String!, withErrorMessage error: String!) {
        print("Placement \(String(describing: placementName)) failed to load because: \(String(describing: error))")

Intercepting Organic Recommendation Items Clicks

By default, TaboolaJS attempts to open clicks in SFSafariViewController. On older iOS versions, where SFSafariViewController is not supported, the clicks are opened in an in-app browser window or in the Safari app.

TaboolaJS enables you to intercept organic recommendation clicks to create a click-through or to override the default way of opening the organic recommended article. For example, for opening organic items as a deeplink into the relevant app screen instead of showing it as a web page.

To intercept clicks, implement the TaboolaJSDelegate and set it in the TaboolaJS object.

For example, you might choose to implement TaboolaJSDelegate in your view controller.

@interface MyViewController () <TaboolaJSDelegate>
@implementation MyViewController
#pragma mark - TaboolaJSDelegate

- (BOOL)onItemClick:(NSString *)placementName withItemId:(NSString *)itemId withClickUrl:(NSString *)clickUrl isOrganic:(BOOL)organic {

    // implement click handling code here
    return YES;
func onItemClick(_ placementName: String!, withItemId itemId: String!, withClickUrl clickUrl: String!, isOrganic organic: Bool) -> Bool {
        return true

Set the delegate correctly on the TaboolaJS SharedInstance:

[TaboolaJS sharedInstance].delegate = self;

The onItemClick method is called every time a user clicks a recommendation, immediately before triggering the default behavior. You can block default click handling for organic items by returning NO.

  • Return NO - abort the default behavior: the app displays the recommendation content on its own (for example, using an in-app browser). NOTE: Aborts only for organic items!
  • Return YES - this enables the app to implement a click-through and continue to the default behavior

isOrganic indicates whether the item clicked was an organic content recommendation or not.

Best practice is to suppress the default behavior for organic items. Instead, open the relevant screen in your app which shows that content.

Listening to errors within the JS tag

It is possible to listen to an error event, a case where Taboola does not serve ads, within the JS tag inside your webview (inside the <body> tag)

<div id="container-id"></div>
<script type="text/javascript">
     window._taboola = window._taboola || [];
     _taboola.push({mode: 'mode-name',
     	container: 'container-id',
     	placement: 'Placement Name',
     	target_type: 'mix'});

// Catch errors within the JS tag
   listenTo: "nocontent",
   handler: function (data) {
     // handle the error here  
// Notice - this part is unique to mobile SDK JS integrations!
_taboola["mobile"] = window._taboola["mobile"] || [];

Working with UIPageViewController

If your app is implementing UIPageView, you can load Taboola's content only when the next screen becomes visible.

  1. Add lazyFetch:true to the mobile JS tag inside the <body> tag (see Step 2 above)
<div id="container-id"></div> <script type="text/javascript"> window._taboola=window._taboola || [];
_taboola.push( {
    mode: 'mode-name', container: 'container-id', placement: 'Placement Name', target_type: 'mix'

// Notice - this part is unique to mobile SDK JS integrations!
_taboola["mobile"]=window._taboola["mobile"] || [];
_taboola["mobile"].push( {
    lazyFetch: true, taboola_view_id: 'view id', publisher: 'publisher-id-goes-here' 

  1. Fetch content when view becomes visible (viewWillAppear)
- (void)fetch {
    [[TaboolaJS sharedInstance] fetchContent:self.webView];

//Full code example:
func fetch() {

//Full code example:

Step 6: Unregister the webview

Do not forget to unregister the webview from step 1 when you done using it:

  • in UIViewController- in viewWillDisappear (Swift and Obj-C)
-(void) viewWillDisappear: (BOOL) animated {
  [super viewWillDisappear: animated];
  if (self.isMovingFromParentViewController || self.isBeingDismissed) {
    [[TaboolaJS sharedInstance] unregisterWebView: _webview completion: nil];
override func viewWillDisappear(_ animated: Bool) {
  if self.isMovingFromParent || self.isBeingDismissed {
    TaboolaJS.sharedInstance()?.unregisterWebView(webView, completion: {})
  • In UICollectionView/UITableView - in dealloc (Obj-C) or deinit (Swift)
-(void) dealloc {
  [[TaboolaJS sharedInstance] unregisterWebView: _webview completion: nil];
deinit {

Step 7: Testing and Examples

You can find code examples on our Github repository.

You can use the following parameters for testing and development. Sponsored items are flagged with an "SC: " prefix in the title; organic items are flagged with an "OC: " prefix in the title

ParametersBelow Article FeedSplit Feed
placement"Feed without video""Split feed with video"
(Split content should be under #split_div DOM element)

Step 8: Submit Build for QA

When you have finished the integration, contact your account manager and send a debuggable (TestFlight or other beta platform) version of your iOS project.

You're done!

Integration Support

Should you have any problems integrating the product, log a ticket with us by emailing your account manager. For non official SLA support you can also check our discussion forum.