EU Nutrition Declaration Format: How to Show It on Your Online Shop
The EU nutrition declaration under Regulation 1169/2011: the required nutrients, order, units, per 100 g basis and rounding, and how to show it as a table on Shopify.
In this guide
If you sell prepacked food to consumers in the EU, the nutrition declaration is one of the pieces of information you must show. When you sell online, it has to be on your product page before the customer buys, not just on the pack they receive.
The format is not up to you. Regulation (EU) No 1169/2011 on food information to consumers sets which nutrients appear, in what order, in what units and on what basis. The Commission’s guidance adds how to round the numbers.
This guide sets out the format from the regulation’s text and shows how to build the table on a Shopify product page. It is general information, not legal advice. For the rest of the mandatory food information, including allergens, see our guide on EU allergen and food information for online food shops.
Why it must be on the product page
Article 14 of the regulation covers distance selling. For prepacked food sold online:
- The mandatory food information must be available before the purchase is concluded. It must appear on the material supporting the sale, which for you is the product page, or be provided by other clearly identified means at no extra cost.
- The only exception is the date of minimum durability or use-by date.
- All mandatory particulars must be available at delivery.
The nutrition declaration is part of that mandatory information, so it belongs on the product page.
What the declaration must contain
Article 30(1) lists the mandatory content:
- energy value
- fat
- saturates
- carbohydrate
- sugars
- protein
- salt
Article 30(2) lets you add one or more of these:
- mono-unsaturates
- polyunsaturates
- polyols
- starch
- fibre
- vitamins and minerals listed in Annex XIII, when present in significant amounts
Where it applies, you may also say near the table that the salt content comes only from naturally occurring sodium.
“Salt” in the regulation means salt equivalent, which Annex I defines as sodium × 2.5. If your lab report gives sodium, convert it.
Some foods do not need a nutrition declaration. Annex V lists them, such as single-ingredient unprocessed products, waters, herbs and spices, salt, and table-top sweeteners. Check Annex V before you assume your product needs one, or that it does not.
The order and units: Annex XV
Article 34(1) says the declaration appears in the order of Annex XV, where appropriate. Annex XV also fixes the units:
| Nutrient | Unit |
|---|---|
| Energy | kJ / kcal |
| Fat | g |
| of which saturates | g |
| of which mono-unsaturates | g |
| of which polyunsaturates | g |
| Carbohydrate | g |
| of which sugars | g |
| of which polyols | g |
| of which starch | g |
| Fibre | g |
| Protein | g |
| Salt | g |
| Vitamins and minerals | units in Annex XIII, Part A |
Leave out the optional rows you do not declare, but keep the rest in this order. A typical declaration has these rows: energy, fat, saturates, carbohydrate, sugars, fibre (if declared), protein, salt.
Show energy in both kJ and kcal.
Per 100 g or per 100 ml
Article 32(2) requires the energy value and nutrient amounts per 100 g or per 100 ml. That column is always there.
On top of it you may add:
- Per portion or per consumption unit (Article 33), if the portion is quantified on the label and the number of portions in the pack is stated.
- Percentage of reference intakes (Article 32(4)), for energy and the mandatory nutrients, per 100 g or 100 ml. Vitamins and minerals, when declared, must also be given as a percentage of their reference intakes (Article 32(3)).
Table or line
Article 34(2) says the declaration is shown in tabular format with the numbers aligned if space permits, and in linear format only if it does not. A product page has space, so use a table.
Article 34(1) also requires the mandatory and optional nutrients to sit in the same field of vision, presented together in a clear format. Do not split the table across tabs or spread rows around the page.
Where the numbers come from
Article 31(4) says declared values are averages, based on one of:
- the manufacturer’s analysis of the food,
- a calculation from the known or actual average values of the ingredients, or
- a calculation from generally established and accepted data.
Energy is calculated, not measured. Article 31(1) and Annex XIV give the conversion factors:
| Component | kJ per g | kcal per g |
|---|---|---|
| Fat | 37 | 9 |
| Carbohydrate (except polyols) | 17 | 4 |
| Protein | 17 | 4 |
| Fibre | 8 | 2 |
| Polyols | 10 | 2.4 |
| Alcohol (ethanol) | 29 | 7 |
| Organic acid | 13 | 3 |
| Salatrims | 25 | 6 |
| Erythritol | 0 | 0 |
Rounding
The regulation does not set rounding rules itself. The Commission’s guidance on tolerances (December 2012), section 6, does. It is guidance for control authorities and businesses, and the one most labels follow:
| Nutrient | Amount per 100 g or ml | Round to |
|---|---|---|
| Energy | Any | Nearest 1 kJ / kcal |
| Fat, carbohydrate, sugars, protein, fibre, polyols, starch | 10 g or more | Nearest 1 g |
| Under 10 g and over 0.5 g | Nearest 0.1 g | |
| 0.5 g or less | “0 g” or “<0.5 g” may be declared | |
| Saturates, mono-unsaturates, polyunsaturates | 10 g or more | Nearest 1 g |
| Under 10 g and over 0.1 g | Nearest 0.1 g | |
| 0.1 g or less | “0 g” or “<0.1 g” may be declared | |
| Salt | 1 g or more | Nearest 0.1 g |
| Under 1 g and over 0.0125 g | Nearest 0.01 g | |
| 0.0125 g or less | “0 g” or “<0.01 g” may be declared |
When an amount is negligible, Article 34(5) also lets you replace the figures with a statement such as “Contains negligible amounts of …” close to the declaration.
A worked example
Say a biscuit has, per 100 g: fat 12.4 g, saturates 3.1 g, carbohydrate 61.0 g, sugars 24.7 g, fibre 3.2 g, protein 7.6 g and salt 0.42 g.
- Energy in kJ: 12.4 × 37 + 61.0 × 17 + 7.6 × 17 + 3.2 × 8 = 1,650.6, which rounds to 1651 kJ.
- Energy in kcal: 12.4 × 9 + 61.0 × 4 + 7.6 × 4 + 3.2 × 2 = 392.4, which rounds to 392 kcal.
- Round each nutrient: fat 12 g, saturates 3.1 g, carbohydrate 61 g, sugars 25 g, fibre 3.2 g, protein 7.6 g, salt 0.42 g.
Calculate energy from the unrounded values, then round. Rounding first can move the energy figure.
Building the table on Shopify
You have three practical options.
Option 1: A table in the product description
Shopify’s rich text editor can insert a table into a product description, and the HTML view lets you paste one in. This works for a few products.
Here is the HTML for the example above:
<table class="nutrition">
<caption>Nutrition declaration</caption>
<thead>
<tr><th scope="col">Nutrition</th><th scope="col">Per 100 g</th></tr>
</thead>
<tbody>
<tr><th scope="row">Energy</th><td>1651 kJ / 392 kcal</td></tr>
<tr><th scope="row">Fat</th><td>12 g</td></tr>
<tr><th scope="row">of which saturates</th><td>3.1 g</td></tr>
<tr><th scope="row">Carbohydrate</th><td>61 g</td></tr>
<tr><th scope="row">of which sugars</th><td>25 g</td></tr>
<tr><th scope="row">Fibre</th><td>3.2 g</td></tr>
<tr><th scope="row">Protein</th><td>7.6 g</td></tr>
<tr><th scope="row">Salt</th><td>0.42 g</td></tr>
</tbody>
</table>
The drawback is upkeep. Values live in free text, and every recipe change means editing HTML by hand. If you sell in several languages, each translation needs the same table again.
Option 2: Metafields and the theme
Store each value in its own product metafield, then render the table in your theme. Shopify’s help on displaying metafields shows how to connect metafields to theme blocks as dynamic sources, or use them in Liquid if you edit theme code.
This keeps values structured and lets you bulk edit them, for example through a product CSV import and export. If values do not appear on the page, see Shopify nutrition and allergen metafields not showing.
A custom Liquid table is a small, well-defined job. If you hire it out, our guide on briefing a developer for a custom Shopify app applies to theme work too.
Option 3: An app with a theme block
An app stores the values for you and adds a block to the product template. You enter numbers per product, and the block renders the table.
Formatting details that matter
- Write “of which” rows under their parent. Saturates sit under fat, sugars under carbohydrate. Indent them or label them “of which”.
- Use the shopper’s decimal separator. German and French shoppers expect 3,1 g, not 3.1 g.
- Translate the row labels for each language you sell in.
- Keep the table in one place, not split across tabs.
- Use real table markup (
<table>,<th scope="row">) so screen readers can read it.
Checklist
- Check Annex V to confirm the product needs a declaration.
- Get average values from analysis, ingredient calculation or established data.
- Calculate energy with the Annex XIV factors, in kJ and kcal.
- Round with the Commission guidance.
- Show values per 100 g or 100 ml, in Annex XV order.
- Use a table with aligned numbers.
- Put it on the product page, before purchase.
FAQ
Is fibre mandatory in the EU nutrition declaration?
No. Fibre is optional under Article 30(2). If you declare it, it goes after the carbohydrate rows and before protein, as Annex XV sets out.
Can I show nutrition values only per portion?
No. Per 100 g or 100 ml is required. Per portion can be added alongside it, under the conditions in Article 33. Article 33 allows per portion instead of per 100 g only in narrow cases, such as percentage reference intake figures.
Do I write salt or sodium?
Salt. The regulation defines salt as sodium × 2.5. If your analysis gives sodium, multiply it by 2.5.
Is a photo of the pack’s nutrition label enough on my product page?
The regulation requires the information before purchase but does not ban images. In practice, a photo is often unreadable on phones, cannot be translated and is hard for screen readers. A real HTML table avoids all three.
Showing it with EU Food Labels
StoreFleet: EU Food Labels lets you enter energy in kJ and kcal, fat, saturates, carbohydrate, sugars, optional fibre, protein and salt per 100 g or 100 ml for each product. Its theme block shows them as a table in Annex XV order, with row labels in ten EU languages and the shopper’s decimal separator. You enter the final values yourself: the app does not calculate energy or round, and it does not cover per-portion values, reference intakes or the other optional nutrients.