Affiliate Product Boxes in WordPress: 4 Approaches

Four ways to put affiliate product boxes and comparison tables on a WordPress site, what each costs in time and page speed, the permission and hosting details that break embeds, and how to keep prices from going stale.

By the AffiFeed teamPublished 7 min read

A product box is the small card with an image, product name, price and a button to the shop. A comparison table is several of them side by side. On an affiliate site they do most of the converting, and they are also where most of the maintenance goes, because the price in the box is wrong the day the shop changes it.

There are four realistic ways to add them to WordPress. None is best for every site; the right one depends on how many products you show, how often prices change and who edits the site.

The four approaches at a glance

ApproachPrice updatesSetup effortBest for
1. Manual blocks (Group, Image, Buttons)By handLow per box, high over timeA handful of evergreen recommendations
2. Feed plugin that imports products into WordPressAutomatic, on the plugin's scheduleMedium to highLarge catalogues, WooCommerce-based comparison sites
3. The network's own ad toolsHandled by the networkLowQuick banners and product ads from one network
4. Hosted widget embedded with a script tagAutomatic, by the serviceLowContent sites that want current boxes without running a feed import
Ways to add affiliate product boxes to WordPress

1. Build the box by hand

With the block editor you can build a decent product box from core blocks: a Group block with an Image, a Heading, a Paragraph for the price and a Buttons block for the link. Save it as a synced pattern if you reuse the same product in several posts, so you only update it in one place.

  • Good: no plugin, no external script, full control of the markup, fast.
  • Bad: every price is typed by hand. If you show prices from Partner-Ads programmes, their terms ask you to keep them updated at least weekly, which is not realistic by hand across dozens of posts.
  • Tip: if you go manual, drop the price and write "see current price" on the button. A missing price is better than a wrong one.

The Button block has a Link relation field under its Advanced settings that sets the link's rel. Add sponsored to every affiliate button; see affiliate links and SEO for why.

2. Import the feed into WordPress with a plugin

Several plugins import network product feeds into your WordPress database and render them with shortcodes or blocks. Examples from the WordPress plugin directory and network integration pages:

  • Datafeedr, listed on Adtraction's integrations page, imports and updates Adtraction product data into WooCommerce, with support for multiple Adtraction markets. It is built for comparison sites and niche stores.
  • Awin Data Feed is a plugin for promoting products from Awin feeds through widgets and shortcodes.
  • affiliate-toolkit is a multi-network plugin for creating and displaying affiliate products.

Check each plugin's current network support and pricing yourself before you commit; it changes. The trade-offs are general: importing thousands of products into WordPress adds database weight and scheduled jobs that run on your hosting, and it makes it very easy to publish a page per product, which is exactly what Google's scaled content abuse policy describes when it mentions scraping feeds to generate many pages. If you import, import only what you plan to use.

3. Use the network's own tools

Networks give you ready-made ad material. Partner-Ads lets you build feed ads (product banners) from its product feeds inside its own interface, and Adtraction has link tools, a product browser and cleanlinks. These are quick, and the network keeps them updated. They usually look like ads, though, and give you less control over layout and comparison across shops. See our Partner-Ads and Adtraction guides for what each offers.

4. Embed a hosted widget

A hosted widget service keeps the product data outside WordPress and gives you a snippet, usually a container element plus a <script> tag, that renders the box on the page. Prices are refreshed by the service. This is the approach AffiFeed uses, so we have an obvious interest here; the WordPress-specific points below apply to any embed.

Who can paste a script tag

WordPress only lets users with the unfiltered_html capability save raw HTML such as <script> and <iframe>. For other users the content is filtered through wp_kses(), which strips those tags. By default only administrators have that capability on a single site, and on multisite only super admins do. In practice: if a contributor or author pastes an embed code and it disappears on save, this is why. Either have an administrator add it, or put the embed in a reusable pattern that an administrator created.

WordPress.com is different

On WordPress.com, tags like script, iframe, style, form, embed and object require a paid plan with hosting features activated. A paid plan alone is not enough; WordPress.com's support pages say you activate the hosting features by installing a plugin. On a free or lower plan, a script embed will not work.

Shopify and other builders

If you also run a Shopify store with content, Shopify's help centre says themes that offer a Custom Liquid section can take custom code there, without editing theme files.

Speed: keep the box from hurting the page

Google's Core Web Vitals thresholds for a good experience are LCP within 2.5 seconds, INP under 200 milliseconds and CLS under 0.1. Product boxes touch all three. The fixes are mostly simple:

  • Reserve the space. A box that appears after the text has rendered pushes everything down and adds layout shift. Give the container a min-height close to the final height.
  • Give images dimensions. Since WordPress 5.5, images with width and height attributes are lazy-loaded by default with loading="lazy", and the browser uses the dimensions to reserve space before the image arrives. For your own HTML boxes, always set both.
  • Load scripts asynchronously. Use async or defer on embed scripts so they do not block the page from rendering.
  • Keep boxes below the first screen lazy. The first image a reader sees should load normally; everything further down can wait.
  • Measure on a phone. Comparison tables that look fine at desktop width often overflow at 375 px. Put wide tables in a horizontally scrolling container instead of shrinking the text.

Keeping prices current

How often you need to refresh depends on the network and the category. Adtraction's feeds are typically updated daily. Partner-Ads asks for price updates at least weekly when you show prices. If you build your own boxes from feed data, cache the result so each page view does not hit the feed, and let the cache expire at a sensible interval.

WordPress has a built-in mechanism for exactly this: the Transients API stores data temporarily in the database under a name and with an expiry time. A minimal shortcode that caches the rendered box for six hours:

functions.php or a small plugin (my_find_product() is your own feed lookup)
add_shortcode( 'product_box', function ( $atts ) {
    $atts = shortcode_atts( array( 'ean' => '' ), $atts );
    $key  = 'pbox_' . md5( $atts['ean'] );
    $html = get_transient( $key );

    if ( false === $html ) {
        $p = my_find_product( $atts['ean'] ); // returns name, price, image, url, shop
        if ( ! $p ) {
            return '';
        }
        $html = sprintf(
            '<div class="pbox">
               <img src="%1$s" alt="%2$s" width="160" height="160" loading="lazy">
               <p class="pbox-name">%2$s</p>
               <p class="pbox-price">%3$s</p>
               <p class="pbox-label">Reklamelink</p>
               <a href="%4$s" rel="sponsored noopener" target="_blank">See price at %5$s</a>
             </div>',
            esc_url( $p['image'] ),
            esc_html( $p['name'] ),
            esc_html( $p['price'] ),
            esc_url( $p['url'] ),
            esc_html( $p['shop'] )
        );
        set_transient( $key, $html, 6 * HOUR_IN_SECONDS );
    }

    return $html;
} );

Two notes on transients from WordPress's documentation: they can disappear before their expiry (for example with an external object cache), so your code must always handle a miss, as above; and they will never be returned after they expire, so a stale price cannot outlive the timeout you set.

Comparison tables

Comparison tables have the same needs as boxes plus a few of their own:

  • Say above the table how it is ordered (by price, by your rating, by a specific spec). EU consumer rules require comparison tools to describe the main parameters behind their ranking and to disclose paid placement, so if commission affects the order, say so.
  • Put the advertising label above the table where it is seen with the buttons.
  • Show the shop name next to each price, and more than one shop per product where you can. Google's reviews guidance notes that readers prefer having several places to buy.
  • On mobile, let the table scroll sideways inside its own container, with the product name column kept narrow.

Disclosure on the box itself

Whatever approach you choose, the box or table needs a visible advertising label where readers see the link. For Danish readers the Consumer Ombudsman's accepted examples are "Reklamelink" or "Annoncelink" directly above or after the link; a footer or disclosure page is not enough. Full details in our disclosure guide.

How AffiFeed does it

AffiFeed is approach 4 for Partner-Ads and Adtraction feeds. You connect your network accounts, filter the products you want, pick a card or comparison layout, and paste two lines into a Custom HTML block: a container div and an async script. Product links carry rel="nofollow noopener sponsored" and images are lazy-loaded. You add the advertising label in your post, right above the widget. The same snippet works in Shopify's Custom Liquid section or any HTML page. See the feature overview.

Sources

Everything factual in this article comes from the pages below, checked in September 2026. Terms and numbers change; check the source before relying on them.

  1. Custom HTML block documentation (WordPress.org)
  2. Roles and capabilities (WordPress.org)
  3. Add code to your WordPress site (WordPress.com Support)
  4. Custom HTML block (WordPress.com Support)
  5. Buttons block documentation (WordPress.org)
  6. Synced patterns: the evolution of reusable blocks (WordPress News)
  7. Integrations (Adtraction)
  8. Awin Data Feed plugin (WordPress.org)
  9. affiliate-toolkit plugin (WordPress.org)
  10. Guide til affiliates brug af hele produktfeeds (Partner-Ads)
  11. Product feeds via Adtraction (Adtraction Help Center)
  12. Spam policies for Google web search (Google Search Central)
  13. Understanding Core Web Vitals and Google search results (Google Search Central)
  14. Lazy-loading images in 5.5 (Make WordPress Core)
  15. Transients (WordPress Common APIs Handbook)
  16. set_transient() (WordPress Developer Resources)
  17. Editing theme code (Shopify Help Center)
  18. Directive (EU) 2019/2161 (Omnibus Directive) (EUR-Lex)
  19. How to write high quality reviews (Google Search Central)
  20. Affiliate links skulle markeres som reklame (Forbrugerombudsmanden)