Updated June 2026, covers child themes against both Hummingbird (PrestaShop 9, SCSS pipeline) and Classic (PrestaShop 8). The override mechanism is identical on either parent.

Here is the moment that turns a good PrestaShop store owner into a frustrated one: you bought a premium theme, you wanted three small things changed, a different heading font, your brand colour on the buttons, a tweak to the product page layout, so you opened /themes/your-theme/templates/catalog/product.tpl and edited it. It looked perfect. Then, six weeks later, the theme author shipped version 2.1 with a security fix and a faster product gallery. You clicked update. Every change you made is gone, overwritten, unrecoverable unless you happen to have a backup you can diff against.

This is the single most common self-inflicted wound in PrestaShop customization, and it has had a proper fix for years: the child theme. This guide is specifically about that. What a PrestaShop child theme actually is at the file-system level, how the override-resolution order decides which file wins, how to build one against Hummingbird or Classic, and exactly where the line sits between "use a child theme" and "this needs a module instead." If what you actually want is to add a snippet of CSS or a tracking script without forking anything, that is a narrower job with its own answer, see custom CSS and JavaScript without breaking updates, and we'll point you back to it at the right moment below.

What a child theme actually is (at the file level)

A child theme is a separate theme directory that declares a parent in its config/theme.yml and inherits everything from it, every template, every asset, every configuration value, while letting you override individual files. It is not a copy of the parent. It is a thin layer that sits on top of it. Any file you do not put in the child is served from the parent; any file you do put in the child wins.

The "So what?" is the entire point of the technique: because the child lives in its own directory, a parent update touches the parent and leaves your work alone. The parent ships v2.1, your overrides keep running on top of v2.1, and you spend your evening doing something other than reconstructing customizations from memory. You get the theme author's bug fixes and speed improvements and your branding, instead of choosing between them.

The override resolution order. The mechanic that makes it work

To trust child themes you need to know precisely how PrestaShop decides which template to render. When a controller asks for a template, the theme rendering layer looks in a fixed order and stops at the first hit:

PriorityLocation it checksWins when…
1 (highest)Child theme: /themes/child/templates/...You placed an override here
2Parent theme: /themes/parent/templates/...The child has no copy
3Module's own front templates (for module hooks)Neither theme overrides that module template

This is why "copy the one file you need, edit the copy" works without breaking anything else: PrestaShop resolves each template independently. Override product.tpl and the rest of the store still renders from the parent. There is no all-or-nothing switch, the child only intercepts the exact paths you populate, falling through to the parent for everything else. That fall-through is the feature, not a limitation: the fewer files you intercept, the more parent updates flow straight through to your store.

config/theme.yml, the file that declares the relationship

The whole inheritance hinges on one file inside your child theme's config/ directory, config/theme.yml. The parent key is what tells PrestaShop "serve everything from this theme unless I override it." A minimal child against Hummingbird looks like this:

parent: hummingbird
name: my-store-child
display_name: My Store Child
version: 1.0.0
assets:
  use_parent_assets: true

The parent value must match the parent theme's directory name (and the parent must actually be installed. A child cannot inherit from a theme that is not present on the server). The name must be unique and must match your child's own directory name. Get either wrong and PrestaShop either falls back to the parent silently or refuses to enable the theme. Both are easier to diagnose once you know it's almost always a name mismatch in this file.

Building a child theme step by step

PrestaShop Theme and Logo screen with child theme active

A child theme does nothing until it is selected as the active theme.

  • Create the directory, for example /themes/my-store-child/, with a config/ directory inside it. Do not copy the parent's files into it. A minimal child theme can be very small, but it must include a valid config/theme.yml declaring the parent, name, display_name and version, with that file in place it renders identically to the parent.
  • Add config/theme.yml at /themes/my-store-child/config/theme.yml with the parent reference shown above.
  • Copy only the files you are actually changing, preserving the relative path. To customize the product page, copy /themes/hummingbird/templates/catalog/product.tpl to /themes/my-store-child/templates/catalog/product.tpl and edit the child copy only.
  • Activate it in the back office under Design → Theme & Logo. Creating the directory does nothing on its own, until you select and use the child theme here, the store still serves the parent. This is the number-one "why isn't my change showing" support question, and the answer is almost always: the child was never activated.

The directory layout of the child mirrors the parent exactly. A template's job is to live at the same relative path in the child as it does in the parent. That path match is how the resolver pairs them.

What belongs in a child theme, and what doesn't

Templates (.tpl), yes, the right tool

Structural markup changes, reordering product page blocks, adding a custom info section, changing how the header renders. Are exactly what template overrides are for. Copy the parent template into the matching child path and edit it. Overriding a module's front template (a file under /themes/[theme]/modules/[module]/views/templates/front/[template].tpl) is a documented technique too, but be aware it is a known weak spot with child themes specifically: PrestaShop's child-theme documentation doesn't cover module-template overrides, and there are open reports of them resolving inconsistently from a child (template caching can serve the parent's copy instead). If you need to re-skin a module's output and you're on a child theme, test it carefully on your version, or put the override on the active theme itself rather than relying on parent/child fall-through.

CSS and JavaScript. Usually the wrong layer to do it in

If your change is purely visual, colours, fonts, spacing, hiding an element, overriding a whole template is the heavy-handed way to do it, and it makes you re-merge that template on every parent update. The lighter, more upgrade-safe move is a stylesheet or script that loads after the parent's assets, which doesn't require duplicating any template logic at all. That is a distinct enough job that it has its own playbook: custom CSS and JavaScript in PrestaShop without breaking updates. The rule of thumb: reach for a template override only when you genuinely need to change the markup; for everything that CSS can do, do it in CSS.

Business logic, neither; that's a module

The hard boundary: if your change is to behaviour, how prices are calculated, how shipping is chosen, what happens at checkout, a child theme is the wrong place entirely. Templates display data; they must not process it. The moment you find yourself writing real PHP logic inside a .tpl file, you have put business code in the presentation layer, where it can't be tested, reused, or updated cleanly. That work belongs in a module (or an override class), not in the theme. A theme decides how the cart looks; a module decides how the cart behaves.

Why "lean" is a hard rule, not a nicety

Every file you override is a file that stops receiving the parent author's fixes. If the parent ships a corrected, more accessible product.tpl in v2.1 and you have your own copy, you will not get that fix. Your copy is frozen at the v2.0 markup until you manually merge the difference. So each override carries an ongoing maintenance tax, and the bill comes due at every parent update.

The discipline that keeps the tax small: override the smallest unit that does the job. Need to add one class to one element? Override that one template, not its parent layout, not the whole catalog folder. Need a colour change? That's CSS, not a template at all. A child theme with four override files is a five-minute update; a child theme with forty is a project every time the parent moves.

Surviving a parent theme update

When the parent author releases a new version, the routine is short because the architecture does the heavy lifting:

  • Update the parent. Your child is a separate directory, so nothing you wrote is overwritten.
  • Diff your overrides against the new parent versions. For each file you copied, compare your frozen child copy with the parent's new copy using any diff tool. This is the one place the maintenance tax is paid, and it's only ever as large as your override count.
  • Merge in anything worth keeping, a bug fix, a new field, an accessibility improvement the author added to a template you override, into your child copy.
  • Test the affected pages, specifically the ones whose templates you override, before and after.

Files you did not override need none of this, they updated automatically the instant you updated the parent. That asymmetry is the entire return on the technique: you do diff-and-merge work proportional only to what you customized, and get everything else for free.

Hummingbird vs Classic, which parent in 2026

Hummingbird is the modern official PrestaShop theme direction for the PS 9 era, while Classic remains common and available, especially on PS 8 and legacy stores. The child-theme mechanism is identical regardless of parent, same config/theme.yml, same resolution order, but the parent you choose changes your asset build:

ParentFront-end toolingChoose it when…
Hummingbird (PS 9-era direction)Modern build (Webpack, SCSS), lighter markupBuilding a new store, or you want the modern baseline and its lighter, faster markup.
Classic (still downloadable)Older, simpler asset pipelineUpgrading an existing Classic-based child and a migration isn't worth it yet.

If you're upgrading from PrestaShop 8 with a Classic-based child theme, you don't have to migrate to Hummingbird on day one, Classic remains available as a separate download, but a new build should start on Hummingbird. Because Hummingbird's stylesheet pipeline is SCSS-based, the way you compile custom CSS differs from Classic; the choice of parent therefore mostly affects your styling workflow, not the override logic. Choosing the right base theme in the first place is a decision worth making deliberately, we cover it in how to choose the right PrestaShop theme for your business.

Common ways people still get it wrong

  • Never activated the child. The directory and config/theme.yml exist, but the store still serves the parent because nobody selected the child under Design → Theme & Logo. Always the first thing to check.
  • Name mismatch in config/theme.yml. The name doesn't match the directory, or parent points at a theme that isn't installed. The child silently falls back or won't enable.
  • Override sprawl. Forty copied templates because "it was easier to copy the whole folder." Every one is now a manual merge on each parent update. Keep it lean by design.
  • No version control. A child theme is custom code. It belongs in Git with real commit messages, so a bad merge after a parent update is one revert away, not a guessing game.
  • "Just this once" on the parent. There is no just once. One direct parent edit becomes twenty, and then the update you can't apply is the security one you most needed. Every change, however small, goes in the child.

The bottom line

A child theme takes about ten minutes to stand up, one directory, one config/theme.yml, the parent name spelled correctly, activated in the back office, and it converts every future parent update from a customization-wipe into a non-event. It is not an advanced technique or an optional best practice; on PrestaShop it is simply the correct way to customize any theme you didn't write yourself. If you are editing parent theme files directly right now, the move is the same regardless of how small your changes feel: create a child theme today and relocate your overrides into it before the next update overwrites them. Then keep it lean, push pure styling into CSS and JS that survive updates, push behaviour into modules, and reserve template overrides for the markup changes that genuinely need them.

Frequently asked questions

Do I have to copy the whole parent theme into my child?

No, and you shouldn't. A child theme inherits everything from the parent by default; you copy in only the specific files you're changing, preserving their relative path. A minimal child can be just a directory with a valid config/theme.yml, and it'll render identically to the parent. The fewer files you copy, the more parent updates flow straight through to your store.

My child theme looks identical to the parent and nothing I changed shows. Why?

Almost always one of two things: the child was never activated under Design → Theme & Logo (creating the directory does nothing on its own), or there's a name mismatch in config/theme.yml, the name doesn't match the child's directory, or parent points at a theme that isn't installed. Check activation first, then the YAML.

Can I put my custom CSS and JavaScript in the child theme?

You can, but for purely visual changes, colours, fonts, spacing, hiding an element, overriding a whole template is heavy-handed and forces a re-merge on every parent update. A stylesheet or script that loads after the parent's assets is lighter and doesn't duplicate any template logic. Reserve template overrides for genuine markup changes; for everything CSS can do, do it in CSS. See custom CSS and JavaScript without breaking updates.

Will my overrides survive when the parent theme updates?

Yes. The child lives in its own directory, so a parent update never touches it. The one task you do owe is diffing each file you overrode against the parent's new version and merging in any worthwhile change (a bug fix, an accessibility improvement). That work is proportional only to how many files you copied, which is exactly why keeping the override count lean pays off.

Can a child theme override a module's front-end template?

It's a documented technique, but it's a known weak spot with child themes specifically. There are open reports of module-template overrides resolving inconsistently from a child because template caching can serve the parent's copy instead. If you need to re-skin a module's output and you're on a child theme, test it carefully on your exact version, or place the override on the active theme directly rather than relying on parent/child fall-through.

The change I want is to behaviour, not appearance. Does it go in the child theme?

No. If you're changing how prices are calculated, how shipping is chosen, or what happens at checkout, that's business logic and it belongs in a module or an override class, never in a .tpl file. Templates display data; they must not process it. A theme decides how the cart looks; a module decides how the cart behaves.

Should a child theme be in version control?

Yes. A child theme is custom code, and it belongs in Git with real commit messages. The payoff shows up after a parent update: if a merge goes wrong, you're one revert away from a known-good state instead of guessing what you changed. It also makes it trivial to see exactly which parent files you've forked and therefore owe a diff at the next update.

Do Hummingbird and Classic need different child-theme setups?

The override mechanism is identical, same config/theme.yml, same resolution order, so the parent choice doesn't change the logic. What it changes is your styling workflow: Hummingbird's stylesheet pipeline is SCSS-based and Classic's is simpler, so how you compile custom CSS differs. Pick Hummingbird for new builds and Classic when you're maintaining an existing Classic-based child.

Share this post:
David Miller

David Miller

Founder, mypresta.rocks

David Miller is a PrestaShop specialist with over a decade of hands-on experience and the founder of mypresta.rocks, a software studio in Tychy, Poland. He builds and maintains a catalogue of 152 PrestaShop modules, including 21 "Revolution" suites spanning SEO, checkout, security, performance, marketing, search, support, and warehouse operations, that improve real stores every day, all tested against PrestaShop 1.7.8, 8.x, and 9.x. He also acts as caretaker for production stores turning over millions in annual sales, so his work is judged on live revenue, not demos. His experience runs the full breadth of ecommerce, performance, security, SEO, and marketing, and reaches beyond PrestaShop to WooCommerce, Shopify, and custom-built systems. On the blog he writes about the code-aware side of PrestaShop: what the platform really does under the hood, what breaks in production, and which fixes hold up.

Comments

No comments yet. Be the first!
Enjoyed this article?

Get our latest tips, guides and module updates delivered to your inbox.

You may unsubscribe at any moment. For that purpose, please find our contact info in the legal notice.

Loading...
Back to top