Shrinkflation is when a pack gets smaller but the price stays the same. 500 g becomes 450 g, the shelf price doesn't move, and you pay 11% more per kilo without noticing.
Two EU countries now make large shops say so in the store:
- France: since 1 July 2024, a ministerial order (Arrêté du 16 avril 2024) requires supermarkets over 400 m² to put a notice next to affected products for two months: "For this product, the quantity sold went from X to Y and its price per [unit] rose by …%". (service-public.fr)
- Hungary: since 2024, government decrees require large food retailers to flag reduced pack sizes for two months, showing the old and new quantity. (njt.jog.gov.hu)
Both rules cover physical shops. Online grocery shops, and the rest of the EU, have nothing like it. So I built ShrinkWatch EU, a free, open-source extension for Chrome, Edge and Firefox. It does the same calculation on grocery web shops.
What it does
- On a product page it shows the price per kg, litre or piece, even on shops that don't show one.
- It remembers the pack size and price in your browser only.
- If you later see the same product smaller for the same price, it warns: "was 500 g for €2.49, now 450 g for €2.49 = +11.1% per unit".
- The popup shows the product's unit-price history as a small chart.
It covers about 70 shops across the EU, Serbia and Bosnia and Herzegovina.
How it reads a product page
The order matters, because shops differ a lot:
-
schema.org JSON-LD (
Product→offers). It's the most reliable when present. Watch out foroffersarrays where the first offer has no price. - Per-shop selectors, for shops without structured data.
- Microdata and Open Graph tags.
-
Visible text near the title, for prices split into elements like
26999.
Reading the pack size is the hard part:
parseSize('Mlijeko 2,8% m.m. 1 l') // 1000 ml (ignores "2,8%")
parseSize('Pivo 6x0,5l') // 6 × 500 ml = 3000 ml
parseSize('Kava 25 dag') // 250 g (Balkan "dag")
parseSize("Sant'Anna Pet Lt 2,0X6") // unit first, Italian style: 12 l
parseSize('Прясно мляко 1 л') // Cyrillic units
When the name has no size, it looks for a labelled field ("Inhalt", "Menge", "Contenu", "Neto količina", …). As a last resort, it works the size out from the shop's own price per kg. That result is marked "≈" and never triggers a warning.
Privacy by design
- No server, no account, no analytics, and no network requests of its own. The extension only reads the page you're looking at.
- A few shops run by default. Every other shop is an optional permission you switch on from the popup, so the extension never gets access to sites you don't use.
- History stays in local extension storage. You can export it to JSON or clear it.
Accuracy
A warning compares what your browser saw before with what the shop shows now. Shop data can be wrong, so the extension says "check the pack", not "this brand is cheating". Every supported shop has a regression test built from a small excerpt of a real product page.
Try it / help
- Website and install: https://emirmrkaljevic.github.io/shrinkwatch-eu/
- Source (MIT): https://github.com/emirmrkaljevic/shrinkwatch-eu
- Missing your shop? Request it. A link to one product page is enough.
This article was written with AI assistance. The code, tests and examples come from the repo.

Top comments (0)