PrestaShop Custom Theme Development
PrestaShop 8.x uses Smarty 3 as the front-office template engine. Default theme is classic (PrestaShop 1.7+). Custom theme development starts with forking classic or building from scratch while respecting directory structure and hook contracts expected by third-party modules.
Theme Structure
themes/mytheme/
├── config/
│ └── theme.yml # Theme manifest
├── assets/
│ ├── css/
│ ├── js/
│ └── img/
├── templates/
│ ├── _partials/ # Reusable components
│ ├── catalog/ # Catalog pages
│ ├── checkout/ # Cart and checkout
│ ├── customer/ # Account pages
│ ├── cms/ # CMS pages
│ └── layouts/ # Layouts: layout-full-width, layout-left-column...
├── modules/ # Module template overrides
│ └── ps_shoppingcart/
│ └── ps_shoppingcart.tpl
└── preview.png
Manifest theme.yml:
name: mytheme
display_name: "My Custom Theme"
version: "1.0.0"
author:
name: "Your Company"
email: "[email protected]"
meta:
compatibility:
from: "8.0.0"
to: ~
assets:
css:
all:
- id: theme-main
path: assets/css/theme.css
media: all
js:
all:
- id: theme-main
path: assets/js/theme.js
priority: 200
position: bottom
global_settings:
image_types:
cart_default:
width: 125
height: 125
small_default:
width: 98
height: 98
medium_default:
width: 452
height: 452
large_default:
width: 800
height: 800
home_default:
width: 250
height: 250
thickbox_default:
width: 1024
height: 1024
Smarty Templates and Context Variables
PrestaShop automatically passes variables from controllers to templates. Product page has access to:
{* templates/catalog/product.tpl *}
{extends file='layouts/layout-full-width.tpl'}
{block name='content'}
<section class="product-detail" itemscope itemtype="https://schema.org/Product">
<h1 itemprop="name">{$product.name|escape:'html'}</h1>
{* Image gallery *}
{block name='product_images'}
{include file='catalog/_partials/product-images.tpl'
product=$product
images=$product.images
coverImage=$product.cover
}
{/block}
{* Price with discounts and taxes *}
<div class="product-price">
{if $product.has_discount}
<span class="price-old">{$product.regular_price}</span>
{/if}
<span class="price current-price" itemprop="price" content="{$product.price_amount}">
{$product.price}
</span>
</div>
{* Add-to-cart form—required hook *}
{hook h='displayProductAdditionalInfo' product=$product}
{include file='catalog/_partials/product-add-to-cart.tpl'}
</section>
{/block}
Webpack Build and Asset Management
PrestaShop doesn't mandate a build tool, but classic theme uses Webpack. Recommended configuration:
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
module.exports = {
entry: {
theme: './src/js/theme.js',
checkout: './src/js/checkout.js',
},
output: {
path: path.resolve(__dirname, 'assets'),
filename: 'js/[name].js',
},
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: { presets: ['@babel/preset-env'] }
}
}
],
},
plugins: [
new MiniCssExtractPlugin({ filename: 'css/[name].css' }),
],
};
Module Template Overrides
Override any module template at theme level without forking:
themes/mytheme/modules/
├── ps_shoppingcart/
│ └── ps_shoppingcart.tpl # Override cart widget
├── ps_searchbar/
│ └── ps_searchbar.tpl # Custom search bar
└── blockreassurance/
└── views/
└── templates/
└── hook/
└── reassurance.tpl
Mobile Responsiveness
PrestaShop doesn't use Bootstrap breakpoints by default in classic theme. For custom theme:
// src/scss/_variables.scss
$breakpoints: (
'xs': 0,
'sm': 576px,
'md': 768px,
'lg': 1024px,
'xl': 1280px,
'xxl': 1440px,
);
// Media query mixin
@mixin respond-to($bp) {
@media (min-width: map-get($breakpoints, $bp)) {
@content;
}
}
// Usage
.product-grid {
display: grid;
grid-template-columns: 1fr;
@include respond-to('sm') { grid-template-columns: repeat(2, 1fr); }
@include respond-to('lg') { grid-template-columns: repeat(3, 1fr); }
@include respond-to('xl') { grid-template-columns: repeat(4, 1fr); }
}
Theme Registration and Activation
# Export theme for transfer
php bin/console prestashop:theme:export mytheme
# Import on another instance
php bin/console prestashop:theme:import /path/to/mytheme.zip
# Activate via CLI
php bin/console prestashop:theme:enable mytheme
# Generate images for all types
php bin/console prestashop:generate:thumbnails --scope=products
Development Timeline
- Basic theme forked from
classicwith redesign: 2–3 weeks - Theme from scratch, complex UI, custom cart/catalog components: 4–6 weeks
- Existing design adaptation (Figma/XD → PrestaShop): 3–5 weeks
- Support all standard modules + multi-language: included above







