Dynamic Remarketing Implementation on Website
Dynamic remarketing differs from regular: ad shows specific products user viewed on site. Person viewed $89,000 laptop—banner shows exactly that laptop with price and photo. Requires technical connection between site, product feed, and ad platform.
Product Feed
Base of dynamic remarketing—feed with product data. Ad platforms pull from it to generate ads.
Google Merchant Center feed format:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>Product Catalog</title>
<link>https://example.com</link>
<item>
<g:id>PRODUCT_123</g:id>
<g:title>MacBook Pro 14 M3 Pro</g:title>
<g:description>Apple laptop with M3 Pro, 18GB memory, 512GB SSD</g:description>
<g:link>https://example.com/catalog/laptops/macbook-pro-14</g:link>
<g:image_link>https://example.com/images/products/mbp14.jpg</g:image_link>
<g:price>89900 RUB</g:price>
<g:sale_price>79900 RUB</g:sale_price>
<g:availability>in stock</g:availability>
<g:condition>new</g:condition>
<g:brand>Apple</g:brand>
<g:google_product_category>Electronics > Computers > Laptops</g:google_product_category>
<g:custom_label_0>bestseller</g:custom_label_0>
</item>
</channel>
</rss>
Feed generation in Laravel:
// FeedController.php
class FeedController extends Controller
{
public function googleMerchant(): Response
{
$products = Product::where('is_active', true)
->where('stock', '>', 0)
->with('category', 'images')
->get();
return response()
->view('feeds.google-merchant', compact('products'))
->header('Content-Type', 'application/xml; charset=UTF-8');
}
}
// routes/web.php
Route::get('/feeds/google-merchant.xml', [FeedController::class, 'googleMerchant'])
->middleware('cache.headers:public;max_age=3600');
Feed updates automatically—prices and stock current.
Event Markup for Google Ads
Dynamic remarketing requires ecomm_prodid (product ID) and ecomm_pagetype (page type):
// On catalog page
gtag('event', 'view_item_list', {
items: products.map(p => ({
item_id: p.id,
item_name: p.title,
item_category: p.category,
price: p.price,
})),
});
// On product page—key event for dynamic remarketing
gtag('event', 'view_item', {
items: [{
item_id: 'PRODUCT_123',
item_name: 'MacBook Pro 14 M3 Pro',
item_category: 'Laptops',
price: 89900,
currency: 'RUB',
}],
});
// On cart page
gtag('event', 'view_cart', {
value: 89900,
currency: 'RUB',
items: cartItems.map(item => ({
item_id: item.product_id,
item_name: item.product_name,
price: item.price,
quantity: item.quantity,
})),
});
Meta Dynamic Product Ads Markup
Meta requires content_ids and content_type: 'product':
// Product view
fbq('track', 'ViewContent', {
content_ids: ['PRODUCT_123'],
content_type: 'product',
value: 89900,
currency: 'RUB',
});
// Cart
fbq('track', 'AddToCart', {
content_ids: ['PRODUCT_123', 'PRODUCT_456'],
content_type: 'product',
value: 94800,
currency: 'RUB',
num_items: 2,
});
// Checkout start
fbq('track', 'InitiateCheckout', {
content_ids: ['PRODUCT_123', 'PRODUCT_456'],
content_type: 'product',
value: 94800,
currency: 'RUB',
num_items: 2,
});
VK Dynamic Retargeting
VK sends events via pixel with product events:
// Product view
VK.Retargeting.ProductEvent('view_product', {
id: 'PRODUCT_123',
price: 89900,
currency: 'RUB',
});
// Add to cart
VK.Retargeting.ProductEvent('add_to_cart', {
id: 'PRODUCT_123',
price: 89900,
currency: 'RUB',
});
// Purchase
VK.Retargeting.ProductEvent('purchase', {
id: 'PRODUCT_123',
price: 89900,
currency: 'RUB',
order_id: 'ORDER_789',
});
Feed for VK sent in YML or CSV format via ad account → "Product Catalog".
Integration via dataLayer + GTM
To avoid code duplication—pass events to dataLayer, GTM translates to needed format:
// Single event — GTM itself distributes across platforms
window.dataLayer.push({
event: 'product_view',
product: {
id: 'PRODUCT_123',
name: 'MacBook Pro 14 M3 Pro',
category: 'Laptops',
price: 89900,
currency: 'RUB',
brand: 'Apple',
stock: 'in_stock',
},
});
In GTM create one tag each for Google Ads, Meta, VK. All three use dataLayer variables—change structure in one place.
Feed ↔ Pixel Connection Check
Critical: product IDs in pixel (content_ids, item_id) must exactly match id field in feed. Mismatch—most common dynamic remarketing setup problem.
// Check—log what's sent to pixel
console.log('Product IDs in pixel:', cartItems.map(i => i.product_id));
console.log('Expected format in feed: e.g. "PRODUCT_123"');
Meta Events Manager "Test Events" section shows data real-time—can verify ID match.
Timeline
Feed generation + event markup for one platform: 1 day. Setup for all three (Google + Meta + VK) via GTM: 2-3 days. Server-Side events to bypass blockers: 1-2 more days.







