Digital Product Passport on PrestaShop 8.x
PrestaShop 8.2 is in extended support and still very widely deployed. It is also the last version where both the legacy and the new product page exist, which makes it a comfortable place to build — and a trap if you build against the wrong one.
Platform facts
| Latest release | 8.2.7, published 4 June 2026 |
| PHP | 7.2.5 minimum, up to 8.1 (8.1 recommended) |
| Database | MySQL 5.7 or MariaDB 10.2 minimum |
| Symfony | 4.4 |
| Default theme | prestashop/classic ^2.2 (a Composer package since 8.0) |
| Status | 8.2.x in extended support since 4 July 2025 — security and critical fixes only, until 10.0 ships. 8.0 and 8.1 are EOL. |
PrestaShop 8 does not officially support PHP 8.2 or 8.3. The compatibility chart
shows a single row for 8.0–8.2 with >= 8.2 = No, and composer.json on
tag 8.2.7 still declares "php": ">=7.2.5". Plenty of hosts run PrestaShop 8.2 on PHP
8.2 in practice and it largely works, but there is no supported configuration claim behind it. If a
vendor tells you their module is "PrestaShop 8 + PHP 8.3 certified", that certification is theirs,
not PrestaShop's.
Where to store passport data
ObjectModel with a custom table, exactly as on 9.x. Define your $definition, ship an
install.sql, and add 'multilang' => true or
'multishop' => true as needed.
Everything in the PrestaShop 9 storage section
applies here — the _lang table conventions, the
Shop::setContext() requirement before saving multilang_shop objects, and iterating
Language::getLanguages(false) to include inactive languages.
Doctrine is available (supported for modules since 1.7.6, ORM ^2.7 on this line) but there is less reason to reach for it here than on 9.x, since the Symfony layer is older.
Designing the schema now with 9.x in mind costs nothing and saves a migration later. The storage layer is the part of a passport module that ports cleanly; the admin UI is not.
Editing passport data in the back office
This is the version where you have to decide which product page you are targeting, because 8.1 introduced the new Symfony product page behind a flag while keeping the legacy one.
The legacy hooks still work here
The ten displayAdminProducts*Step* hooks — MainStepLeftColumnMiddle,
OptionsStepBottom and the rest — are genuinely dispatched in 8.2.7, from the product
page Twig panels. displayAdminProductsExtra works too, and
controllers/admin/AdminProductsController.php still exists.
Build against these and your module dies on PrestaShop 9 — silently, because the
hook names remain registered there while nothing dispatches them. If you expect to support 9.x at
any point, use actionProductFormBuilderModifier instead, which is available from 8.1
onwards and is the same API on both versions.
The forward-compatible route
actionProductFormBuilderModifier exists from 8.1 and works identically on 9.x. Custom
product tabs via NavigationTabType also arrived in 8.1. Writing your passport tab
against these means one code path for 8.1, 8.2 and 9.x — which is worth the small extra effort over
the legacy hooks.
For saving, actionAfterUpdateProductFormHandler and its siblings work here as on 9.x.
actionProductSave works everywhere and is the safest choice if you want one hook across
all supported versions.
Avoid actionAdminProductsControllerSaveBefore. It only fires on the legacy product page
and cannot fire at all on PrestaShop 9, since the controller it derives from no longer exists.
Showing the passport on the storefront
Identical to 9.x. displayProductExtraContent is the right hook for a passport tab, and
it must return an array of
PrestaShop\PrestaShop\Core\Product\ProductExtraContent objects — a bare object is
silently dropped.
See the PrestaShop 9 front-office section for the full code example and the reasoning; none of it differs on this version.
displayProductAdditionalInfo, displayAfterProductThumbs,
displayFooterProduct, displayProductActions and
displayReassurance are all available and not deprecated.
Since 8.0, hook aliases emit deprecation notices. Register
displayProductAdditionalInfo, not productActions or
displayProductButtons. Also: registering a hook without implementing its method now
throws in developer mode, which is a useful early warning that a port has gone wrong.
The public passport URL
Unchanged from 1.7 and identical to 9.x: a ModuleFrontController in
controllers/front/, linked with Link::getModuleLink(), with clean URLs via
the moduleRoutes hook.
One thing you can do here that you cannot on 9.x is expose a loose PHP entry point directly. Do not — PrestaShop 9 forbids it, and it is the kind of shortcut that turns into an emergency during an upgrade.
Version-specific gotchas
What already changed coming from 1.7
If you are maintaining a module that started on 1.7: the PHP floor rose to 7.2.5, Symfony went from
3.4 to 4.4, and Twig from 1 to 3. Non-injected, non-public services were dropped from the container.
The bundlename:path:file.html.twig template syntax is invalid — use
@bundlename/path/to/file.html.twig. Translations moved from
/app/Resources/translations/ to /translations/.
The classic theme left the core
From 8.0, themes/classic/ is no longer in the core tarball. It is the Composer package
prestashop/classic. If your passport styling assumed it could patch theme files in
place, that assumption is gone.
Plan the 9.x port now
The three things that will break: the legacy product form hooks, $this->get() in
Symfony controllers, and any reliance on trans() escaping output. The first is
avoidable today by using actionProductFormBuilderModifier. The other two are
worth auditing before you are under upgrade pressure.
Questions
Should we build a passport module against 8.x legacy hooks or the new form builder?
actionProductFormBuilderModifier, available from 8.1. It is the same API on 8.1, 8.2 and 9.x, so you write one code path. The legacy displayAdminProducts*Step* hooks work on 8.x but are dead on 9, and they fail silently there rather than erroring.