SDK DocumentationRecipesAnnouncementsSupport Forum
AndroidiOSAnnouncementsSupport Forum
SDK Documentation

Feed via JS

📍

DEPRECATION NOTICE

On March 31, 2025, Taboola will sunset SDK 2.

Before then, please make sure to migrate to SDK 3 for iOS.

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() {
        super.viewDidLoad()
        
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        config.preferences.javaScriptCanOpenWindowsAutomatically = true
        webView = WKWebView(frame: view.frame, configuration: config)
        
        view.addSubview(webView)
        
        // implement the `with: self` to get events (optional - see step 3)
        TaboolaJS.sharedInstance()?.registerWebView(webView, with: self)
        
        webView.loadHTMLString(appHtml, baseURL: URL(string: "https:"))
    }

🚧

Important

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;
               e.id = i;
               f.parentNode.insertBefore(e, f);
          }
     }(document.createElement('script'),document.getElementsByTagName('script')[0],
     'https://cdn.taboola.com/libtrc/publisher-id/mobile-loader.js',
     'tb_mobile_loader_script');
</script>
  • 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["mobile"].push({
        taboola_view_id:'view id',
        publisher:'publisher-id-goes-here'
});
</script>
  • 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

🚧

Important!

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

Step 5: Additional Integration Information (Optional)

Delegates

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
_taboola.push({
   listenTo: "nocontent",
   handler: function (data) {
     // handle the error here  
   };
  
// Notice - this part is unique to mobile SDK JS integrations!
_taboola["mobile"] = window._taboola["mobile"] || [];
_taboola["mobile"].push({
   publisher:"publisher-id-goes-here"
});
</script>

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' 
}

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

//Full code example: https://github.com/taboola/ios-sdk-examples/tree/master/Taboola%20SDK%20ObjC%20Samples/Taboola%20SDK%20ObjC%20Samples/SDK%20JS
func fetch() {
	TaboolaJS.sharedInstance()?.fetchContent(webView)
}

//Full code example: https://github.com/taboola/ios-sdk-examples/tree/master/Taboola%20SDK%20Swift%20Sample/Taboola%20SDK%20Swift%20Sample/SDK%20JS

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) {
  super.viewWillDisappear(animated)
  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 {
	TaboolaJS.sharedInstance().unregisterWebView(webView)
}

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
publisher"sdk-tester-demo""sdk-tester-demo"
placement"Feed without video""Split feed with video"
(Split content should be under #split_div DOM element)
pageUrl"https://blog.taboola.com""https://blog.taboola.com"
pageType"article""article"
TargetType"mix""mix"
mode"thumbs-feed-01""thumbs-feed-01"

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.