Updated June 2026, hook names and the native module table below apply to PrestaShop 1.7, 8 and 9. Positions are managed under Design → Positions in modern back offices.

Sooner or later every PrestaShop store hits the same wall: you need a piece of content the theme was never designed to hold. A free-shipping bar above the product grid. A "ships before Christmas if you order by Dec 19" notice in the header. A pair of trust badges right under the add-to-cart button. None of that lives in a product description, a CMS page, or a category. It needs to appear in a specific spot on specific pages, and stay there through theme updates. That is exactly the job a custom HTML block does: it drops arbitrary markup into a named position in your store without you opening a single template file.

This guide is about that one task, getting custom HTML into the right place in PrestaShop and controlling where it shows. It is not about styling (that is a separate discipline; see custom CSS and JavaScript in PrestaShop without breaking updates) and it is not about renaming static pages in your menu (CMS page display names covers that). Here we stay on the mechanics of placement.

Why HTML blocks instead of editing the theme

You could open themes/your-theme/templates/catalog/product.tpl and hard-code that badge. Two reasons not to. First, the next theme update, or a child-theme resync, can overwrite your edit and the badge silently vanishes. Second, a template edit is invisible to anyone who isn't a developer: you can't turn it off for a weekend sale or swap the wording from the back office. When created through a module such as ps_customtext or a dedicated HTML-block module, the content is stored in the database and rendered through PrestaShop's hook system, so it survives upgrades and you manage it from Modules or Design without touching a file. So what? You change a promotional message at 9am before a flash sale and remove it at midnight, yourself, with zero risk to the theme.

The native modules that already do this

Before buying anything, know that PrestaShop ships with three free modules that cover the common cases. They are commonly available in standard Classic-based installs, and can be installed or enabled from the Module Manager if missing:

ModuleTechnical nameWhat it gives youWhere it lands
Custom text blockps_customtextA rich-text (TinyMCE) editor that outputs free HTMLHome page (displayHome) by default
Bannerps_bannerA banner image with a link at the top of every pageTop of page (displayBanner)
Link List (Link Widget)ps_linklistStructured link blocks (e.g. your CMS pages)Footer (displayFooter) by default

For most "I just need a paragraph of HTML somewhere" jobs, ps_customtext is the answer. Go to Modules → Module Manager, search "custom text," click Configure, paste your HTML into the editor (switch the editor to source/code view with the <> button if you want clean markup), and save. By default it renders in displayHome. The catch, and the reason merchants outgrow it, is that ps_customtext gives you one editable block bound to one hook, with no per-page targeting and no scheduling.

Understanding positions: the hooks that decide "anywhere"

"Anywhere" in PrestaShop is not literally any pixel. It is any registered hook. A hook is a named insertion point the theme calls while rendering a page, and a module attached to that hook gets its output dropped in. You can see every position in Design → Positions (older versions: Modules → Positions), which lists each hook and the modules currently transplanted into it, in render order. These are the positions that matter for custom content:

  • displayBanner, full-width strip at the very top, above the header. The home of store-wide announcement bars and free-shipping-threshold messages. Seen before any scroll, on every page.
  • displayNav1 / displayNav2 / displayTop, inside the header band (left/right of nav, top utility row). Good for a short phone number, a country/shipping note, or a slim USP line.
  • displayHome, the body of the home page, interleaved with product carousels and category tiles. For value propositions and featured promo sections.
  • displayProductAdditionalInfo. On the product page directly beneath the add-to-cart area. This is where delivery promises, guarantee badges and payment-method icons earn their keep, because the shopper reads them at the exact moment they hesitate.
  • displayFooterBefore / displayFooter, above and within the footer, on every page. Trust badges, newsletter prompts, secondary links.
  • displayLeftColumn / displayRightColumn. Sidebars (where your theme has them). Filter helpers, category promos, support callouts.

The practical move when you don't know a position by name: open the page you want to edit, and in Design → Positions use Transplant a module (the "Hook a module" button). The dropdown lists every hookable position, and the help text describes where each one renders. You can also drag a module up or down within a hook to control whether your block sits above or below, say, the category banner.

The part native blocks can't do, and why merchants reach for a dedicated module

The native ps_customtext is fine until you need any of the things real stores actually need:

  • Per-page / per-controller targeting. "Show this size guide only on the Shoes category, only on product pages." Native blocks render on their hook everywhere it fires; they have no page filter.
  • Multiple placements and activation control. A "Last day for Christmas delivery" bar should be a named block you can enable, disable and move without editing a template. Date-window scheduling is a separate feature; do not assume a block module has it unless you see date fields in its back office.
  • Multiple independent blocks in the same hook. One ps_customtext instance is one block; juggling five different messages across five positions gets unwieldy fast.
  • Multishop-aware content. Show different block content per shop/language where the module stores language and shop rows. Customer-group targeting is a separate rule layer, not something the stock text block exposes.
  • Consent-aware blocks. If the block carries tracking or embedded media, a cookie-category gate lets it render only when the visitor has not denied that category.

This is the gap a dedicated HTML-block module fills: a library of named blocks, each assigned to one or more hooks, with page-type placement, layout choice, multilingual/shop content, cookie-category gating and, in modules such as MPR HTML Blocks, template injection for positions where the theme forgot to expose a useful hook. So what does that buy you? You stop editing templates and stop installing a new module every time marketing wants a banner; you build a block once and point it at the hook or page area where it belongs. If page-aware content and cleaner placement are what you're after, that capability is the dedicated-module step beyond the native block, same principle, but with multiple blocks, placement records and template injection managed from the back office.

Writing the HTML so it survives the editor

One avoidable headache: TinyMCE and PrestaShop's HTML filtering can rewrite or remove unsupported markup depending on configuration. The rich-text editor will "tidy" markup it doesn't recognise, and security filtering may strip inline styles or reformat tags when you save. If your block disappears or loses styling after a save, that's usually the culprit. The fixes, in order of preference:

Keep the block markup boring and class-based. This is the kind of source view content that survives editor cleanup and leaves all styling to the theme stylesheet.

<section class="promo-bar promo-bar--shipping">
  <p><strong>Free delivery this weekend.</strong> Orders over 75 EUR ship free until Monday.</p>
  <p><a href="/delivery">See delivery conditions</a></p>
</section>

A storefront product page showing a product photo, price and add-to-cart, with content in its Description tab

A storefront product page with content shown in its Description tab.

  • Toggle the editor's source code view (the <> / "Tools → Source code" button) and paste markup there, not into the WYSIWYG pane.
  • Keep styling in a class, not inline. Put a class such as promo-bar on your block and define .promo-bar in your theme's custom stylesheet. The editor leaves class attributes alone, and you get the styling-survives-updates benefit described in custom CSS and JavaScript without breaking updates.
  • If a block must run JavaScript, attach it through the proper asset hook rather than pasting a <script> tag into the editor. Inline scripts in content blocks are fragile and easy to break on save. That mechanism is its own topic, covered in the same CSS/JS guide.

Keep blocks fast and on-brand

Two design disciplines decide whether a block helps or hurts. First, match the theme. Pull the same font stack, the same accent colour and the same spacing rhythm your theme already uses, so the block reads as part of the store rather than a bolted-on afterthought. Second, stay concise. A banner is one sentence plus a call-to-action; a trust strip is recognisable icons, not a paragraph. The value of a block is in what it adds at the right moment, not in how much you cram into it.

On performance: every block is extra markup, and image-heavy blocks are the usual weight offenders. Serve correctly sized, compressed images, lean on CSS for layout and effects instead of loading a library, and if you have several blocks live at once, check their combined effect in your browser's network panel. Page speed is one input Google weighs, so a stack of bloated banners can quietly work against the rest of your on-page effort. Keep the markup light and the win stays a win.

A quick decision guide

Your needUse
One block of HTML on the home page, no rulesNative ps_customtext
A banner image with a link at the top of every pageNative ps_banner
Footer link lists / menusNative ps_linklist
Multiple blocks with page-type placement, consent gating or template injectionA dedicated HTML-block module
A markup change that's truly structural and theme-deepA child theme, never edit the parent

The reason HTML blocks are worth mastering is the one they started with: they let a store owner, not a developer, put the right message in the right place at the right time, and pull it back just as easily, without ever risking the theme. Learn the position names, lean on the free native blocks for the simple jobs, reach for a dedicated module the moment you need multiple blocks, page-aware placement or theme-safe injection, and keep every block light and on-brand. Do that and a stock PrestaShop install starts speaking in your store's own voice at exactly the moments that move a sale.

Frequently asked questions

Does "anywhere" really mean any spot on the page?

Not literally. It means any registered hook. A hook is a named insertion point the theme calls while rendering a page, and your block's output drops in wherever that hook fires. You can see every available position under Design → Positions. If the exact spot you want has no hook, that's where a dedicated module's template-injection feature earns its place, since it can target positions the theme never exposed as a hook.

Which native module should I use for a simple HTML block?

For a paragraph of HTML, use ps_customtext, search "custom text" in the Module Manager, click Configure, and paste your markup (use the <> source view for clean code). For a banner image with a link at the top of every page, use ps_banner; for footer link lists, ps_linklist. All three ship free with Classic-based installs and store content in the database, so it survives theme updates.

Where do I put a trust badge or delivery promise on the product page?

The displayProductAdditionalInfo hook, which renders directly beneath the add-to-cart area. That's where guarantee badges, delivery promises and payment-method icons earn their keep, because the shopper reads them at the exact moment they hesitate. Hook your block there via Design → Positions → Transplant a module rather than editing product.tpl.

My block lost its styling or vanished after I saved it. Why?

Almost always TinyMCE or PrestaShop's HTML filtering "tidying" the markup on save, the editor rewrites tags it doesn't recognise, and security filtering can strip inline styles. The fix: paste into the editor's source code view, not the WYSIWYG pane, and keep styling in a CSS class (define .promo-bar in your theme stylesheet) rather than inline. The editor leaves class attributes alone.

When do I outgrow ps_customtext and need a dedicated module?

The moment you need any of: per-page or per-controller targeting (e.g. a size guide only on the Shoes category), multiple independent blocks managed centrally, multishop or multilingual block content, cookie-consent gating for blocks carrying tracking, or placement in a spot the theme exposes no hook for. ps_customtext gives you one block bound to one hook with no page filter. Fine until those needs appear.

Can I run JavaScript inside an HTML block?

Don't paste a raw <script> tag into the editor. Inline scripts in content blocks are fragile and easy to break on save, and they bypass PrestaShop's asset management. Attach the behaviour as an external .js file through the proper asset hook instead, exactly as covered in custom CSS and JavaScript without breaking updates. Keep the block to markup and a CSS class.

Do too many blocks slow the store down?

They can. Every block is extra markup, and image-heavy blocks are the usual weight offenders. Serve correctly sized, compressed images, lean on CSS for layout instead of loading a library, and if several blocks are live at once, check their combined cost in your browser's network panel. Page speed is one signal Google weighs, so a stack of bloated banners can quietly undercut the rest of your on-page work.

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