# SDK Recipes: Advanced Integration Debug, native ads, and custom rendering patterns # SDK Recipes: Advanced Integration Advanced integration patterns for debugging, native ads, and custom rendering. *** ## Recipe 8: "I need native/in-feed ads" **Problem:** You want ads that blend with your content feed. ### Native Ad Implementation **1. Mark element as native slot** ```html

Real article 1

Real content...

Placeholder title

This content will be replaced by native ad

Real article 2

Real content...

``` **Key classes:** * `nativeinfeed` - Marks element as native ad container * `data-collapse="1"` - Hides element if no ad available **2. Automatic slot detection** With `autoslot: 1`, the SDK automatically finds `.nativeinfeed` elements: ```javascript dlApi = { target: "SITE/AREA", autoslot: 1, // Auto-detects native slots async: 1 }; ``` **3. Restore content if no ad** When a native slot gets no ad, restore the editorial content: ```javascript dlApi.cmd.push(function(dlApi) { dlApi.on("afterDestroySlot", function(event, slot) { // Check if this was a native slot var el = document.getElementById(slot.div); if (el && el.classList.contains('nativeinfeed')) { // Restore editorial content el.innerHTML = `

Real article title

Real editorial content here...

Read more `; // Show the element again el.style.display = ''; } }); }); ``` ### Manual Native Slot Definition For more control, define native slots manually: ```javascript dlApi = { target: "SITE/AREA", autoslot: 0, // Manual control async: 1, cmd: [] }; dlApi.cmd.push(function(dlApi) { // Define multiple native slots dlApi.defineSlot("infeed1", "native-slot-1", { pos: 1, native: true }); dlApi.defineSlot("infeed2", "native-slot-2", { pos: 2, native: true }); dlApi.fetch(); }); ``` ### Track Native Ad Events ```javascript dlApi.cmd.push(function(dlApi) { dlApi.on("afterDisplay", function(event, ad) { if (ad.native) { console.log("Native ad displayed:", ad); // Track to analytics } }); dlApi.on("empty", function(event, slot) { console.log("No native ad for:", slot.name); // Restore editorial content }); }); ``` ### SDK Objects Used * Native ad classes: `nativeinfeed` * `dlApi.defineSlot()` - Manual slot definition * `dlApi.on("afterDestroySlot")` - Slot removal event * `slot` with `native` property *** ## Recipe 9: "I need custom ad rendering" **Problem:** You need special ad formats or custom templates. ### Custom Template Registration **1. Register your custom renderer** ```javascript dlApi.cmd.push(function(dlApi) { dlApi.registerTemplate({ // Template identifier (from campaign setup) tplCode: "1746213/CustomFormat", // Your rendering function renderAd: function(ad) { console.log("Rendering custom ad:", ad); // Create custom HTML structure var container = document.createElement("div"); container.className = "my-custom-ad"; // Access ad data container.innerHTML = `
${ad.fields.headline}

${ad.fields.headline}

${ad.fields.description}

${ad.fields.cta || 'Learn More'}
`; // Insert into slot var slotElement = document.getElementById(ad.div); slotElement.appendChild(container); // IMPORTANT: Track impression if (ad.meta.impression) { var pixel = new Image(); pixel.src = ad.meta.impression; } // Track click properly var link = container.querySelector('a'); link.addEventListener('click', function(e) { // ad.meta.adclick already prepended to href console.log("Custom ad clicked"); }); } }); }); ``` **2. Ad object structure** The `ad` parameter contains: ```javascript { // Ad metadata meta: { adclick: "https://click-tracking-url/", // Click tracker prefix impression: "https://impression-url/", // Impression pixel adid: "12345", // Ad ID cmpid: "67890" // Campaign ID }, // Creative data (depends on template) fields: { headline: "Product Title", description: "Product description...", image: "https://cdn.example.com/image.jpg", url: "https://destination-url.com", cta: "Shop Now", price: "$99.99" // ... other custom fields }, // Slot reference div: "ad-slot-id", // Container element ID slot: slot, // Slot instance // Template info tpl: "1746213/CustomFormat" } ``` ### Multiple Custom Templates ```javascript dlApi.cmd.push(function(dlApi) { // Product carousel template dlApi.registerTemplate({ tplCode: "1746213/ProductCarousel", renderAd: function(ad) { // Render carousel with multiple products var carousel = createCarousel(ad.fields.products); document.getElementById(ad.div).appendChild(carousel); trackImpression(ad.meta.impression); } }); // Video template dlApi.registerTemplate({ tplCode: "1746213/VideoAd", renderAd: function(ad) { // Render video player var player = createVideoPlayer(ad.fields.videoUrl); document.getElementById(ad.div).appendChild(player); trackImpression(ad.meta.impression); } }); // Interactive template dlApi.registerTemplate({ tplCode: "1746213/Interactive", renderAd: function(ad) { // Render interactive experience var interactive = createInteractive(ad.fields); document.getElementById(ad.div).appendChild(interactive); trackImpression(ad.meta.impression); } }); }); ``` ### Important: Tracking Requirements **Always preserve click and impression tracking:** ```javascript renderAd: function(ad) { // ✓ CORRECT - Impression tracking if (ad.meta.impression) { var pixel = new Image(); pixel.src = ad.meta.impression; } // ✓ CORRECT - Click tracking (prefix preserved) var link = document.createElement('a'); link.href = ad.meta.adclick + ad.fields.url; // ✗ WRONG - Missing impression // (No tracking pixel) // ✗ WRONG - Broken click tracking link.href = ad.fields.url; // Missing adclick prefix! } ``` ### Template with Error Handling ```javascript dlApi.cmd.push(function(dlApi) { dlApi.registerTemplate({ tplCode: "1746213/SafeTemplate", renderAd: function(ad) { try { // Validate required fields if (!ad.fields.image || !ad.fields.headline) { console.error("Missing required fields:", ad); return; } // Render ad var container = createAdElement(ad); document.getElementById(ad.div).appendChild(container); // Track impression if (ad.meta.impression) { new Image().src = ad.meta.impression; } } catch (error) { console.error("Template render error:", error, ad); // Fallback to standard rendering ad.renderStandard(); } } }); }); ``` ### Access Ad Instance Methods The `ad` object is an ad instance: ```javascript renderAd: function(ad) { // Access ad methods console.log("Ad ID:", ad.adid); console.log("Campaign ID:", ad.cmpid); // Watch visibility var view = ad.watchVisibility(); view.on('viewed', function() { console.log("Custom ad was viewed"); }); // Access counter for tracking ad.counter.finish(); // Mark ad as loaded } ``` ### SDK Objects Used * `dlApi.registerTemplate()` - Register custom renderer * `ad` object - Ad data with fields and metadata * `ad.meta` - Tracking URLs and metadata * `ad.fields` - Creative field data * `ad` instance - Ad object with methods *** ## Next Steps * **Having issues?** See [Troubleshooting Guide](./troubleshooting-guide.md) * **Need more examples?** See [SDK Recipes](./sdk-recipes.md) * **Deep dive?** See [DL API SDK Reference](/reference/dl-api-sdk.json)