Every release, including the mistakes.

Affiliate Box for Amazon, newest first, in the words of the release that shipped it. Fixes are written out in full rather than filed under "various improvements" — if a bug cost you commission, you should be able to find out exactly when and how.

Updating

The free plugin comes from the WordPress.org directory, so WordPress offers each new version as an ordinary update on the Plugins screen. Premium updates the same way, through your licence. Your settings, tracking IDs and saved boxes are untouched either way.

  1. 2.27.2 current
    • Removed a Freemius licensing key from the free package. The paid edition carries a hundred-character key issued by Freemius; their build server strips it when it produces the free edition, and while the free edition came from there, that was taken care of. Since the free package is built here instead, the key travelled with it for four days. It is not used at runtime — the SDK does not know it — but a key of any kind has no business in a package anyone can download. The build now removes the line itself and refuses to finish if it is still there afterwards, and it flags anything else in the package that reads like a secret.
    • Every admin screen now loads its JavaScript from a file instead of carrying it in the page. WordPress.org does not allow JavaScript written into the markup, and the free edition submitted to the directory was held up for exactly that. Thirteen blocks moved into admin/js/affiliate-box-admin.js; what PHP contributes — a nonce, translated sentences, a lookup table — is handed over in front of it. Nothing changes on screen, and the file is cached by the browser instead of being re-sent with every page.
    • Fixed: the geotargeting test printed its two result sentences with the placeholders still in them. “Detected: %1$s, via %2$s.” appeared literally instead of naming the country and the source, and so did the routing sentence below it. The pattern that was meant to fill them in could never match — a regular expression in which $ means “end of text” rather than a dollar sign. The one-placeholder messages on the same screen were unaffected, which is why it survived this long.
    • The Amazon search in the box editor speaks your language now. Eleven messages — Searching Amazon…, No results for those keywords., Invalid ASIN and the rest — were written into the script in English and reached no translation file. They are ordinary translatable strings from this version on.
    • The readme documents every external service. What is contacted, when, what is sent, and under whose terms: the Amazon Creators API, the two country lookups that geotargeting can fall back on, and Freemius for licensing. Required by wordpress.org, and worth having regardless — the country lookups send a reader’s IP address out of the EU, and your privacy policy has to name that.
    • Fixed: a product box saved by an older version printed PHP warnings on the page. Fields have been added to a box over the versions — a colour, a button label, a line above the name — and the stored boxes were never brought up to date. The renderer read those fields without asking whether they were there. Nothing was visible: PHP substitutes an empty string and the box looks right. With WP_DEBUG on, though, a row of “Undefined array key” warnings appeared in the middle of the post, and the same in the box editor and the box list. Every one of those places now completes a stored box against the full set of fields before reading it, so a field added tomorrow cannot bring the warnings back.
    • The number in the product box list is now taken from where the rest of the plugin takes it — the stored index rather than a copy of it inside the record.
    • Removed Tested up to from the plugin header, where it is not a valid field. It stays in the readme, which is where WordPress reads it.
    • Under the surface: the free edition can no longer contain a script block at all — the build checks for it and refuses. The dead remains of the geotargeting test used to travel with it, naming two services that edition never contacts.
  2. 2.26.0
    • The affiliate disclosure has a third answer: once per page. It was in every box or nowhere, and neither works once an output gets small — a grey compulsory sentence under a one-line Compact strip is longer than the strip, and five product mentions in an article meant five copies of the same line. Leaving it out is not an option: Amazon requires it, and a silent omission is exactly the kind of mistake this plugin exists to prevent. Once per page draws it with the first box and leaves it off the rest, so it still sits above every link it covers.
    • A fifth layout: Button only (auto × 38 px). No card at all — just the call to action, for after a paragraph that has already named the product. No picture, no title, no price, because they are in the sentence above. This is the layout the disclosure setting unlocks; without Once per page every button would carry its own grey line and stop being a button.
    • Picture on the right, a tick box in the box editor. For several boxes one after another: three identical arrangements read as a catalogue, alternating sides read as an article somebody wrote. It belongs to the box rather than to the placement, which is what makes the alternation hold wherever the box appears.
    • A rotation keeps the disclosure through a swap. With once per page, only the first output would normally carry it — and a rotation draws all of its boxes, showing one and swapping it in the reader’s browser. Each of them now carries the line, because exactly one is ever visible. Without that, a page could lose its disclosure the moment the box changed.
    • Under the surface, again: the disclosure was read in six places across five files, each with its own copy of the same rule. It now lives in one.
  3. 2.25.1
    • Fixed: the Compact layout was only one line for square pictures. Its height was capped through the width of the thumbnail alone, so a portrait product photo made the row 134px tall instead of 78, and a very tall one 246px — while the layout is named “Compact (640 × 78 px)” and the handbook calls it one line. Amazon’s standard product image is square, which is why it looked right in testing; books and posters are not. Both Compact and Hero now cap the picture’s height as well, and the picture keeps its proportions inside that square.
    • In post and Sidebar are deliberately left alone: their height has never been capped, they promise nothing about it, and changing that would move every box on every site that already uses them.
    • Fixed: the live preview on the General tab stacked its layouts. Switching the Default layout added the new class but only removed the two old ones, so picking Compact and then Sidebar left the box wearing both — and the preview looked different depending on the order you clicked in. Reported from a real screen. It now clears any class by its prefix, so it cannot go stale again when a layout is added.
  4. 2.25.0
    • Two new layouts for a product box, and every list that offers one now says how big it is. The four names appear the same way on all four screens — the General tab, the box itself, the block and the widget — each with its largest size in brackets, so you can pick by the space you have.
    • Compact (640 × 78 px) — one line. Thumbnail, name, price, button. For naming a product in the middle of a paragraph without cutting the paragraph in half, and for a short list of recommendations in a sidebar. An article that mentions eight products cannot carry eight cards. The name is trimmed with an ellipsis rather than wrapped, and the stars and brand line are left out — one line has to stay one line. On a phone it folds into two.
    • Hero (960 px) — the box at the top of a review. Wider, bigger picture, bigger name, and a new field on the box: Line above the name. Small capitals above the product — Our pick, Best value. Leave it empty and none appears; it is what makes a Hero a recommendation rather than just a wider box. It shows in every layout that has room for it, and travels with the self-contained version of a box.
    • The sidebar layout fills the column now. It was capped at 320px. Measured across seven column widths: from 340px up the box stopped growing, so in a 420px sidebar a hundred pixels sat empty beside it while the theme’s own widgets filled the column. The cap is now 400px — still a cap, because in a wide footer column a box without one becomes a pillar.
    • Under the surface: the list of layouts stood in thirteen places — eight checks across five files, four dropdowns and three tables in the handbook — and two of those dropdowns used different words for the same two layouts. It now lives in one place. That matters because the old failure was silent: a check that did not know a new layout fell back to the old one without a word.
    • Fixed: Health called a box unused when it was inserted with the block. The content search read post text for shortcodes, and a block is an HTML comment, not a shortcode — so a post that carried a box only as a block was never even fetched from the database. The box then had no “Used on” line, and Health, which names boxes appearing in no post, said so about a box that was on a page. It now reads shortcodes, blocks — including one inside a Columns block — and rotations.
    • A box inside a rotation counts as used, in every post that shows the rotation. Otherwise the boxes that only live in a rotation would all have looked abandoned.
    • The line above the name shares a line with the brand when both are filled in — OUR PICK · AMAZON. Measured, they are the same size and both in capitals; stacked they read as clutter above the title rather than as two facts. It also gives every box one line back.
  5. 2.24.0
    • Rotation: a different box at the same spot each day. A box in a sidebar stays there for months, and a regular reader stops noticing it after the third visit. Pick the saved product boxes that should take turns, choose every hour, day or week, and put the rotation on the page with the Affiliate Box block, the widget, or [affiliate_box_rotate key="…"].
    • It survives a page cache — which is where this kind of feature usually breaks without saying so. The box on show is chosen from the clock rather than at random, so a freshly built page is already right; the other boxes ride along inside the page without loading a single picture; and a page served from an older cache puts itself right in the reader’s browser. Everyone sees the same box on the same day, which is also what makes a report about it mean anything.
    • It doubles as an A/B test. Reports already counts each box on its own, so two boxes for the same product — a different photo, a different button, a different layout — tell you which one earns its place.
    • A rotation holds product boxes, not tables, lists or reviews: those differ so much in height that the page would jump on every change. Ten at most. Delete a box that sits in a rotation and it drops out; the rest carry on, and a rotation down to one box says so on its tab.
  6. 2.23.0
    • A block for the editor. Add Affiliate Box, choose from a list of everything you have saved, and the box appears while you choose — drawn by the plugin itself, not an imitation of it. Until now the only way in was to copy a key out of the settings page and paste [affiliate_box box="a7f3k2c9"] into a Shortcode block, and that key tells you nothing about which box it is.
    • One block for all four kinds. Product boxes, comparison tables, bestseller lists and reviews stand in one list, with the kind written beside each name. Four separate blocks would have put back the question “which one do I add?” — the question the merged tab and the merged shortcode were built to remove.
    • Width and image size sit beside the block, because they belong to the place and not to the box: the same box goes wide in an article and narrow in a sidebar, and the settings page cannot know which. Colours stay on the General tab on purpose — one box should not be two colours in two posts.
    • A widget, for sidebars. On a modern theme the block works in widget areas as well; the widget is for sites running Classic Widgets, where blocks are not offered. It defaults to the narrow layout, and a widget with nothing chosen draws nothing at all — not even its heading.
    • Nothing already in a post changes: the block runs the same shortcode, so a block and a pasted shortcode produce exactly the same box.
  7. 2.22.2
    • The date beside prices is gone again. 2.22.0 put an “as of …” stamp next to every price fetched from Amazon, because the Product Advertising API licence asks for one unless the data is refreshed hourly. The rule is real; the conclusion was not. It is a licence you accepted, not the plugin’s to enforce on your pages — and the way established publishers satisfy it is the other half of that “or”: they refresh constantly and earn the exemption. Open any well-known review site and there is no date beside the price. A stamp wedged into every box cost more in trust than the rule costs in risk. Handbook §19.2 now states the rule plainly and what to do about it, instead of the plugin deciding for you.
    • Fixed: on a geotargeted box, a link that was never meant to leave the page was rewritten to Amazon. The script that points a box at the reader’s own store rewrote every link inside it. That held while a box had only an image, a title and a button — and broke the moment 2.22.0 added one that was a jump within the same page: clicking it for an explanation took the reader to Amazon instead, in the same window, because an in-page jump carries no “open in new tab”. In-page links are now left where they are.
    • The affiliate disclosure no longer grows with your theme. Its size was purely relative to the surrounding text, so in a block theme with 21px body copy the line came out at 15.9px — nearly as large as the paragraph beside it, and the heaviest grey block on the card. It is now capped at 13px and floored at 10px: still clear and conspicuous, no longer shouting.
  8. 2.22.0
    • Every price now carries the date it was fetched, because Amazon requires it. The Associates Program IP License asks for a date/time stamp next to any displayed price unless the data is refreshed hourly. The nightly refresh runs daily, and without a licence a box is only fetched when you press Refresh — so the rule applied to every box, in both versions, and the plugin was showing neither the stamp nor the disclaimer that goes with it. Boxes now read $69.99 (as of 3 Sep 2026 14:11 CEST – Details).
    • The required disclaimer appears once per page, not once per box — reachable from every box through that “Details” link, exactly the pattern Amazon’s own example uses. Three boxes on a page do not mean three copies of the same paragraph, and it is not printed at all on pages that show no price.
    • A price you typed yourself gets no stamp, because there is no fetch time to state and the plugin will not invent one. The same applies if you fetch a product and then edit the price by hand: the stamp is dropped rather than claim a time for a figure that was never fetched.
    • Export a box as a self-contained shortcode. WordPress exports posts, not settings, so an article moved to another site arrives without your boxes. The Shortcode column now offers Self-contained version, which writes the whole box out in full — with the price map per store. What it costs is written next to the button: the copy is never refreshed again, and it cannot carry the box’s own colours or its show/hide switches.
    • Fixed: the preview on the General tab only ever showed the button text. It was handed no colours at all, and its layout and image size were hard-coded, so choosing a colour scheme and saving changed nothing — while the line above it promised the opposite. It now follows every setting, and it follows them as you change them, without saving.
    • The style attributes for the button and the box are now built in one place instead of two. That duplication is what let a correction in 2.18.0 reach one of four callers and leave a dark button measuring 1.0:1.
  9. 2.21.2
    • Fixed: every box quietly overruled the button text and the button colour. A new box was created carrying “Buy on Amazon” and the orange as its own values rather than as placeholders, so it saved a decision nobody had made. Nothing looked wrong — the copy was the same colour — until you changed the setting on the General tab and not one box followed. Existing boxes are released from it where the value is exactly the shipped one, so a label you typed on purpose stays.
    • All of the appearance settings now live in one place. Layout, image size and the box colours were on the Product Boxes tab, button text and button colour on General. The split was technically sound and still wrong: nobody looks for a setting by its scope. They are together under How every box looks on the General tab, and one click on a colour scheme now sets the button, the background and the title colour at once — it used to take the same choice twice, on two tabs.
    • The Product Boxes tab is a list again. A settings form used to sit underneath it, so you scrolled past your own data into a form.
    • The box editor asks less of you. One line at the top says what to actually do; Stores and Appearance fold away when they hold nothing and state what they hold when they do — “every other country gets a search”, “2 settings of its own”. Nothing was removed.
    • Marketplaces: a save bar that appears when you change something, and regions that fold. Twenty-two fields with one button at the bottom is how a Tracking ID gets typed and never saved. A region opens by itself when it holds an ID, when it holds your fallback store, or when it holds a store that links out with no Tracking ID of its own — that last one is empty and still the most expensive row on the page. The same bar is on Geotargeting and General.
    • Removed again: “Own link target”, added one version ago. A saved box is built around its ASIN — the nightly refresh, Health and the store rows all hang off it — so a link pointing elsewhere let the price and the button disagree. [affiliate_box url="…"] in a post still works for a storefront or a search page.
    • Fixed twelve strings that still named the two tabs merged in 2.21.0, and taught doccheck.py to compare the tab names the plugin uses against the tabs it actually has, so that class of mistake cannot come back.
  10. 2.21.1
    • Fixed: ten places still spoke of the two tabs that 2.21.0 merged. The heading above the list said “Saved Boxes” while the tab above it said “Product Boxes”; the getting-started signpost on General still offered a choice between them; and the shortcode reference described a builder screen that no longer exists and called a saved box “a different shortcode”. Found on a screenshot of a real installation.
    • doccheck.py gained a tenth check, so that class of mistake cannot come back: the tab names the plugin itself uses are now compared against the tabs it actually has. The existing check held the documentation against the strings in the source — and a wrong heading was one of those strings, so it proved its own correctness. The new check found one more place by itself.
    • A box built from the Amazon search now names itself. The Internal label field is not filled when you click a search result, and the list showed a column of “(no label)” — the one field whose whole purpose is finding a box again later. Left empty, it is now taken from the product title, shortened to its head, with a trailing “with” or “and” removed so it reads as a name rather than a cut-off line.
    • The empty search term is now named where it costs something. With geotargeting on and no Search term for other countries, every reader outside a box’s own store gets a search for the shortened English title. That works, which is why nobody notices, and it finds very little: “Eismaschine” beats “ice maker” on amazon.de. The field says so now, but only while geotargeting is actually on.
  11. 2.21.0
    • Product Box and Saved Boxes are one tab. Both of them built a product box. The difference was where the data lived — in the post, or in the database — and that is an architecture decision nobody should have to make before they know what they are building. There is now one screen, Product Boxes, one way in, and one shortcode.
    • A box is inserted with [affiliate_box box="a7f3k2c9"]. That key is permanent and belongs to the box. It is deliberately not the row number: move your content to another site and numbers are handed out again in a different order, which would point a post at a different product under your affiliate link with nothing on screen to say so.
    • Nothing in an existing post changes. [affiliate_box asin="…"] and [affiliate_box_pro id="N"] are still rendered exactly as before. They are simply no longer offered as a way of working, because a product written into a post text is never refreshed — it is the data that ages worst.
    • A saved box can now carry its own ASIN, image, title and price per store. Until now only a hand-written shortcode could do that, so a saved box sent every reader outside its own store to a search page. Add rows under One product, several stores; a store with no row still falls back to the search, which is the second-best answer and never a wrong one.
    • The nightly refresh is about ten times faster — ten products per Amazon request instead of one, grouped by store.
    • Fixed: the nightly refresh never had a raised time limit. That was set only behind the Run now button, so on a host allowing 30 seconds the nightly job stopped after roughly twenty products, silently, and the rest was never fetched. It now also works oldest-first, so whatever is left over is picked up next time, and it reports what it did not reach instead of only what it did.
    • Only stores with a Tracking ID of their own are refreshed. Amazon credits a sale to the ID of the store it happens in, so a store without one earns nothing and geotargeting was already never sending anyone there. A price nobody will see is not worth an Amazon request.
    • Fixed: an Amazon answer without a title or an image emptied those fields, on every post using that box. The fallback that was supposed to keep the old value could never fire.
    • Fixed: a review count of “11,482” typed into a saved box became 11, and a discount typed as “22%” rendered as “-22%%”. The repair for both existed, but only on the screen that has now gone.
  12. 2.20.1
    • Fixed: a comparison table’s button had unreadable text at rest. 2.19.0 taught it to follow the button colour set on General, but the stylesheet set its label with !important — so the calculated colour lost and only took effect while the pointer was over it. Measured on teal: 3.1:1 sitting still, correct on hover. Now 5.5:1 either way.
    • Fixed: that button also jumped back to orange on hover, whatever colour was set. It keeps its colour and darkens slightly instead.
    • Fixed: the colour schemes on a bestseller list stayed clickable without a licence, while every other control on that screen was locked.
    • Found by going through every line changed since 2.14.0 rather than re-running the existing tests. An existing site that has changed no colours was measured to render exactly as before: nine colours checked, and none of the new CSS variables reaches the page.
  13. 2.20.0
    • Fixed: three of the seven colour schemes made a bestseller list’s price unreadable. A scheme’s accent is designed to be a surface — a button, a ribbon — where the text on it is calculated. A bestseller list uses it as text, and Amazon orange as text on white measures 2.1:1. Schemes now carry a second shade of the accent, darkened until it works as text; all seven now reach at least 4.7:1 on both row backgrounds.
    • Fixed: the readability report claimed “readable” for colours you had just changed. It was built from the saved state and never moved. Measured: after picking a scheme it still read “the weakest of the six combinations is 4.8:1” while the price field had just been set to a colour at 2.1:1. It now recalculates as you choose — the same report, from the same code, asked for again.
    • A bestseller list finally shows what you are choosing. Two model rows with the odd and even backgrounds and all three text colours on them, following every change. Five colour pickers, and until now no picture of them anywhere.
  14. 2.19.0
    • Fixed, properly this time: a dark button colour made its own label invisible. 2.18.0 corrected one of the four places that paint a button; the other three kept the old code. A saved box with a dark button measured 1.0:1 — black on near-black — while the same colour reached 17.7:1 through [affiliate_box]. Saved boxes, search grids and review boxes now measure the label like everything else. All four measured at 17.7:1.
    • Fixed: a colour picker changed nothing until you saved. The pickers wrote their value into the field but announced it to nothing, so the live models sat still while you dragged. They now emit an ordinary event, set up in the one place every picker in the plugin is created.
    • The button colour set on General now reaches comparison tables too. The General tab promises it reaches “product boxes, comparison tables and bestseller lists alike”; measured, a table’s button stayed orange whatever was set. The promise is now true.
    • Saved Boxes gets what the other colour screens had. A model of the card beside the fields — image, title, price, button — following every change, and a readability check on the text against the background. It was the only colour screen in the plugin with neither.
  15. 2.18.0
    • Fixed: a dark button colour made its own label invisible. The stylesheet fixed the text at near-black and let only the background be changed — 7.9:1 on the default orange, and a measured 1.0:1 on a dark blue. Anyone who entered a dark brand colour got a button with no readable text and nothing said why. The label’s colour is now measured against the background and set to black or white, whichever reads.
    • The same seven colour schemes on every screen that has colours — General, Product Box, Saved Boxes, Bestsellers, Reviews and Comparison Tables. One list, one set of names, so a name means the same thing wherever you meet it. Each screen fills the fields it has: five for a bestseller list, three for a comparison table, one for the button.
    • Comparison tables can take a dark scheme. Their body text now follows the column background by the same calculation, so a dark table is readable instead of dark-on-dark.
    • Every scheme is checked in every role it is used: body text against both backgrounds, secondary text against the background, button label against the accent. The worst of the twenty-eight measurements is 5.0:1.
    • The review box’s six pairs and the comparison table’s six schemes were separate lists that shared four names with different values. They are one list now.
  16. 2.17.0
    • Comparison tables get ready-made colour schemes, the same idea the review box has had. Six of them, one click sets the whole table, and each has been checked for readable text.
    • The colours moved to the level a table is actually decided on. There were eight — a background and a title colour per column — and none for the table itself. A comparison is read across; four independently painted columns are the one thing it cannot afford. Now three colours apply to the whole table: the accent on the ribbon, the column background, and the ground that sets the top pick apart.
    • The top pick’s colour can be set at all. Its warm ground and its ribbon were fixed in the stylesheet — the most consequential choice in the whole table, and the only one with no control.
    • The ribbon’s text colour is calculated, not chosen. Dark text reaches 7.9:1 on Amazon orange but only 3.1:1 on teal, so no fixed colour serves every accent. The plugin measures and takes the better of black or white — the same calculation the page uses, in one place, asked for by the editor rather than repeated in JavaScript.
    • A model beside the fields shows how the three colours sit together and follows every change.
    • Fixed: the hint under a column background read “a warm cream suits the top pick” — but the stylesheet already paints it warm cream, so following the advice replaced the marking and choosing anything else erased it.
    • Leaving a colour blank still means the plugin’s own is used: nothing is written into the page unless you chose it.
  17. 2.16.0
    • A “Start here” panel on the General tab, for a fresh installation only. It lists the three steps from installed to earning — Tracking ID, Amazon API, first box — says which of them are required and which is optional, ticks off what is done and outlines what comes next.
    • It removes itself. Once the two required steps are done it never appears again: nothing to dismiss, no setting to find. A box counts as built whether you saved one or wrote a shortcode straight into a post, so neither way of working leaves the panel standing.
    • The step outlined in blue is always a required one. Highlighting the optional API step would have contradicted the line above it, which promises two steps to earning.
    • For anyone set up in a way the plugin cannot see, I am set up already — hide this removes the panel for good.
  18. 2.15.0
    • Marketplaces now comes before Amazon API. A Tracking ID is the more basic of the two: without one the plugin earns nothing at all, while the API is optional — product data can be typed in by hand. The other way round does not work, because Amazon requires a Tracking ID on every API request.
    • “Test connection” no longer fails for a reason that has nothing to do with your credentials. With no Tracking ID entered anywhere, the request was refused before it ever reached Amazon and reported as Test request failed with a developer line in the error table. Nothing is sent now; the tab names what is missing and offers a button straight to the field.
    • The Amazon API tab states what it needs before you start typing: a request carries two things, a credential and a Tracking ID, and only one of them lives on that screen.
    • “Tag to be used” is no longer a whisper. (none — will fail) was true, but grey and easy to read past. It now carries the amber marking the rest of the plugin uses for “something is missing here”.
    • Fixed: changing the marketplace in the test picker always said (US fallback), whichever store actually acts as the fallback. The PHP had been corrected, the JavaScript beside it had not — so the same line claimed two different things depending on whether you had just loaded the page or switched the picker.
  19. 2.14.0
    • Comparison tables: a feature label now opens its boxes straight away. Type “Weight” at the top and a Weight box appears in all four columns as you type. Before, the boxes only existed after saving — so the one screen where you fill a table in could not be filled in on the first pass.
    • Renaming a label keeps what you already typed. The boxes follow the row, not the wording, so “Weight” → “Weight (kg)” carries the values with it.
    • Each column says what becomes of it. Shows as column 2, or Empty — left out of the table. Blank columns are dropped when the table renders and the rest move up; until now that only became apparent in the finished post.
    • The top pick is marked in the builder, in the same colour throughout, so the highlighted column is visible while you work rather than after publishing.
    • The four columns no longer run off the screen. Two fields side by side forced every column to 738 pixels — 1476 in a box 1100 wide — so the right-hand column was cut off. Fields now follow the width of their column.
    • A label used twice is flagged and saved once. Two identical labels made two identical rows.
    • Fixed: on a new table the warning read “3 feature rows have no value in any column: , ,” — it was counting the three blank starter rows, which never become rows at all.
  20. 2.13.1
    • The Premium mark is back on the tabs, as a small dot in the corner. It lies over the tab instead of beside it, so it takes no width at all: the bar stays a single row at every window size, and the paid tabs carry their mark again. Written out, the five marks cost 266 pixels — a fifth of the bar, and exactly what was missing for one row.
    • Hovering a marked tab says what the dot means, and screen readers read it out.
    • The tab cards on General write the word out in full. They sit in a grid with a row of their own, so a wider label moves nothing — and what does not have to be shortened should not be.
  21. 2.13.0
    • Check all products. One button in Health goes through everything used on a published page and asks Amazon whether it still exists. It says beforehand what it costs — “7 products are used on published pages. Asks Amazon 3 times.” — counted per store, because one request asks one store.
    • What it checks that nothing else did: a shortcode written straight into a post. The nightly refresh never touched those; they carry their data in the post text and never ask Amazon again, which is why they age worst.
    • It runs in batches with a progress bar, one request about every second. A new Associates account may make one request per second, and thirty in a row would also run past the time limit PHP is given on many hosts.
    • Find a replacement. Where one product is gone, the button opens that box with the old product title already in the search field — almost always the right search term, because it describes the thing being replaced.
    • Each saved box carries its own state in the list — Not on Amazon any more, ASIN is unusable, Last refresh failed once — with its own replacement link. Where several are affected, the finding leads here, because one button can carry one address and not three.
    • Drafts stay out of the check: a product in an unpublished post costs nothing and should not cost Amazon requests either.
  22. 2.12.0
    • Health now says what a finding costs. “In the last 30 days this cost you 1,030 of 5,860 box views — 17.6 %.” The whole argument of this plugin is that these mistakes cost commission silently; Health listed them and never put a figure on it, although Reports has had the figure since 2.5.0. It turns a task into an invoice.
    • A curve beside the count, and a sentence: “10 fewer than 2 weeks ago.” A screen that only ever scolds is one you stop opening. This is the only part of it that can show progress.
    • Where one click fixes it, the button is on the finding — Refresh all now for prices older than a week, Search my posts when the content search has not run. Everything else still leads to the tab, because it needs a decision rather than a click.
    • Findings are sorted by weight, not by section. “Only one store has a Tracking ID” — two minutes of work, affects every link — used to sit level with a credential secret of the wrong length. A finding that carries a figure outweighs one that does not, because it is evidence rather than a rule.
    • A figure appears only where Reports is on and has counted something. An invented number would be worse than none.
  23. 2.11.0
    • The plugin now knows which post uses which box. Once a day it reads through your published posts and notes the shortcodes they carry. Nothing else knew this: Reports counts a saved box as itself, because the same box lives in many posts at once.
    • The Saved Boxes list says where each box is used, with links to the posts.
    • Health names saved boxes that appear in no post. They cost nothing, but they are carried along in every list and every count.
    • Shortcodes written straight into a post are now on the map. The nightly refresh never touched them — they carry their data in the post text and never ask Amazon again, which is exactly why they age worst. Their ASINs are recorded for the checks to come.
    • Escaped shortcodes, single quotes and unquoted ids are all read correctly, because WordPress’s own shortcode parser does the reading. Drafts stay out: a broken box in an unpublished post costs nothing.
    • Search my posts at the top of Health starts the search immediately; the line beside it says when it last ran.
  24. 2.10.0
    • Health now names the saved boxes Amazon no longer returns. The nightly refresh already fetches every saved box; until now it kept a count — “24 product boxes, 3 errors” — and threw away which three. It knew exactly. Now it writes it down, at the cost of no extra Amazon requests at all.
    • Three findings, because three different things need doing: a product that is gone (replace it), an ASIN that is not ten characters (correct it), and a single failure (wait — Amazon also refuses for reasons that have nothing to do with the product).
    • One failure is never enough to call a product dead. It takes a second failure on a different day. A false red would send you through thirty posts looking for nothing, and after that nobody believes the report again. Pressing Refresh twice in a row therefore changes nothing either.
    • Missing API credentials are deliberately not counted against a box: they affect every box at once and already have a finding of their own.
  25. 2.9.0
    • Fixed: the Clicked column per country was always 0. A click was recorded without the routing mode it belonged to, so it never reached the country row — the question “which countries click” could not be answered at all. Clicks recorded from now on land where they belong.
    • A day-by-day chart. One bar per day for the chosen period: box views in light blue, the clicks among them in green, on the same scale. Clicks are usually a thin strip — that is the honest picture, and a second axis would have made them look equal. Hovering a bar gives the exact figures, including for a day with nothing.
    • Posts with a box in them, with the link. For a hand-written [affiliate_box], which is counted per post. A saved box is counted as itself, because the same box lives in many posts at once.
    • A rate in grey rests on fewer than a hundred views. 0.0 % out of 28 means “too little data”, 0.0 % out of 5,000 means “this box does not work” — the two should not look alike.
    • Download CSV for the raw rows of the period, for anything the screen does not answer.
    • Fixed: the total read 0 without geotargeting, above a table full of views. It came from rows that only exist when a reader’s country is known.
    • Says plainly what is not counted: readers without JavaScript, requests that look like a crawler, and that these are box views rather than visits.
  26. 2.8.2
    • Fixed: the review gallery did nothing. Clicking a thumbnail left the big photo where it was — no error, no clue. The script was never loaded: it only loads when it is registered, and a post whose content is rendered early (Rank Math builds its meta description that way) reaches the box before registration has happened. The files are now registered on init, so the answer is right whenever the content is rendered.
    • Fixed: a photo across the top sat between two grey bands. The frame was fixed at 4:3, so a 16:9 photo left 110 pixels of grey. The frame now takes the shape of the lead photo — no bands — while a gallery still keeps its height when you switch photos, because the frame stays put.
    • New review boxes now default to “Photo beside the text” and “Lead photo with a gallery.” Both read better in a normal article column. A single photo shows no thumbnails, and a narrow column stacks by itself, so neither default gets in the way. Existing boxes keep what they were saved with.
  27. 2.8.1
    • Fixed: the review markup produced an invalid product snippet. Google read the embedded product as a product of its own and asked for one of offers, review or aggregateRating — and it had none, because the first two are deliberately left out. The markup now puts the product on the outside and the review inside it, which is Google’s own shape for the review of a product. The condition is met through the review, so neither omission has to be taken back.
    • Found in the field with Google’s Rich Results Test on 25 August 2026: the review snippet was valid, the product snippet was not.
    • A review box without a score now produces no markup at all. A rating is what makes a review snippet, and a review without one would make the product invalid in turn.
  28. 2.8.0
    • Review boxes now describe themselves to search engines. A block of JSON-LD travels with the box, naming what was reviewed, by whom, with which score, and with which pros and cons. Nothing changes for the reader. Switch it off under Reviews → Structured data for search engines.
    • Pros and cons become positiveNotes and negativeNotes — schema.org has a home of its own for them, and it fits exactly the two lists the editor already keeps.
    • Deliberately left out: price and “in stock”. Amazon is the seller, not you. A price copied into markup goes stale between refreshes while a search engine reads it as a promise. Also left out: aggregateRating, because a review box holds exactly one rating, not an average.
    • No promise of stars in Google. The markup makes the review machine-readable; what a search engine shows for it is the search engine’s decision, and for a reviewer’s own verdict on a product it often shows nothing.
    • The markup sits with the box, not in the page head: remove the shortcode and the markup goes with it, and two boxes produce two blocks.
  29. 2.1.35
    • The plugin is now called “Doozly Affiliate Box for Amazon”. WordPress.org asks for a distinctive term at the start of a plugin name, and the old one began with common functional words. “Amazon” stays at the end after “for”, which is the pattern they recommend.
    • The text domain moves with it, from affiliate-box-for-amazon to doozly-affiliate-box-for-amazon.
    • Nothing else changes: the [affiliate_box] shortcode, every setting and every saved box keep working exactly as before.
  30. 2.1.34
    • Fixed: the Amazon API tab always claimed it needed a paid plan. A red “Pro plan required” badge sat in its heading unconditionally, because the variable meant to decide that was never assigned. The Amazon API is part of this free plugin and always has been — nothing on that tab was ever restricted.
    • New: Documentation and Support links in the plugin’s row on the Plugins screen, and a support line at the foot of the settings page. Until now the plugin never said where to turn when something went wrong.
    • Published by Doozly. The author, copyright and project URL now point to doozly.link. The plugin’s own name is unchanged.
    • The translation template was rebuilt. It had been maintained by hand and was missing 160 of its 496 strings, which left a third of the plugin untranslatable.
  31. 2.1.33
    • New: Amazon API. Connect a Creators API credential and fill a box from an ASIN or a keyword search — title, image, price, star rating and review count arrive from Amazon. One credential per region; the secret is stored encrypted and never displayed again.
    • New: Product Box builder. A visual editor for [affiliate_box] with a live preview that renders the real box, not an approximation. Fill the fields, copy the finished shortcode.
    • New: Saved Boxes. Save a box and reuse it by ID. Edit it once, every page that shows it follows.
    • New: star ratings. rating and rating_count render half-star-accurate stars above the price.
    • New: discount display. original_price and savings_pct show a struck-through former price and a percentage badge.
    • Reworked the settings screen: one tab per job, each with its own colour, and a way back to the overview from every edit screen.
    • Rebuilt the product box stylesheet — larger images, calmer typography, contrast that passes WCAG AA on the button.
  32. 2.0.6
    • Fixed: the call-to-action button could render without any text on it. If you had ever cleared the Button text field and saved, every box showed a coloured button with no label — the default only applied while the setting had never been saved at all. “Buy on Amazon” now steps back in whenever the stored value is empty.
  33. 2.0.5
    • New: the settings page warns when an Associates Tracking ID does not match the store it is filed under — a -20 United States ID in the German field, for example. Amazon runs the programme separately per country and normally does not credit a purchase to another programme’s ID, so this is easy to get wrong and invisible afterwards: the links look perfectly normal and simply earn nothing. It is a warning only; the value is always saved.
  34. 2.0.4
    • New: a section at the bottom of each settings tab explains what the paid version adds, with the lead text matching the tab you are on. It appears only on this plugin’s own settings screen — no dashboard notices.
  35. 2.0.3
    • Tested against WordPress 7.0 on PHP 8.2: activation, every settings tab, every shortcode render path and uninstall, with WP_DEBUG on and no notices or deprecations logged.
  36. 2.0.2
    • New: per-marketplace ASINs, images and titles. asin_de, asin_com, image_de, title_de and so on for every supported store — the same product usually carries a different ASIN in each Amazon marketplace. The value matching the box’s marketplace wins over the plain attribute.
  37. 2.0.1
    • Fixed: saving the General tab or the Marketplaces tab silently reset every Product Box setting. Layout, image size, button text, all three colours and the affiliate disclosure fell back to their defaults. Each tab now owns its own settings group, so a save only ever writes the fields on that tab.
    • Fixed: an invalid colour value reset the button to white, making the call-to-action invisible on a white box. Each colour field now falls back to its own default.
  38. 2.0.0
    • First release prepared for the WordPress.org directory.
    • Removed all licensing and license-check code.
    • Added an abfa_shortcode_atts filter so add-ons can auto-fill box attributes.
  39. 1.0.0
    • Initial public release.

The numbers jump from 2.8.0 to 2.1.35. The releases in between were written up in German only, and translating them here would make this our account rather than the plugin’s — so they are left out rather than reworded.

What each of these does in practice is covered in the documentation.