Updated June 2026, applies to PrestaShop 1.7 through 9. The Classic theme still ships no scroll-to-top button; the focus here is placing one in the spot PrestaShop won't overwrite on update.

Here is the part most "add a scroll to top button" guides skip: on a PrestaShop store the question is rarely whether you want one. It is where the button actually comes from, because that determines whether it survives your next theme or core update. PrestaShop's default classic theme does not ship a back-to-top button, but many premium themes add one, and a page builder might inject a second. So before you paste any JavaScript, the real work is figuring out what your store already has, and adding the missing piece in the one place PrestaShop won't overwrite.

This guide is the PrestaShop-specific implementation: where a button typically lives, which module and hook let you add one without editing the parent theme, and how to make it survive updates. For why the button moves the needle on engagement and orientation at all, the UX case, the mobile argument, the psychology, that ground is covered in why a back to top button surprisingly matters, which also carries the full vanilla-JS implementation snippet. We won't repeat either here.

Check what your store already renders

Start by ruling out a button you didn't know you had. PrestaShop's classic theme (1.7 through 9.x) does not include a native scroll-to-top button, its footer (themes/classic/templates/_partials/footer.tpl) and compiled JavaScript (themes/classic/assets/js/theme.js, built from the _dev/js/ sources) contain no such element. So on a stock classic store there is nothing to find. Many premium themes, however, do ship their own back-to-top arrow that fades in once you scroll past the fold.

So the first diagnostic is concrete: scroll your homepage and a long category page on both desktop and mobile. If a button already appears bottom-right and works, your theme is providing it and you don't need to add anything. You need to style it, which is a CSS job (see below). If nothing appears. Which is the default on the classic theme, or it appears but is broken, then you're adding one, and the next sections are about doing that the PrestaShop way.

The wrong way: editing the parent theme

The tempting move is to open footer.tpl or theme.js in the active theme and edit them directly. It works for about as long as it takes you to update the theme, the next update overwrites your files and your button vanishes, usually noticed weeks later when nobody's looking. This is the single most common reason a "tiny" front-end tweak turns into recurring maintenance.

The discipline that prevents it is the same one PrestaShop enforces everywhere: never edit the parent theme. If you're customising the look of a purchased theme, the override belongs in a child theme; we walk through exactly how that works and why in child themes in PrestaShop. For a self-contained widget like a scroll button, though, you usually don't even need to touch theme files at all. Which is the next section.

The update-safe way: an HTML block plus custom JS/CSS

A scroll-to-top button is three small things: a bit of markup, a few lines of JavaScript to show/hide it and animate the scroll, and some CSS to position and style it. None of that needs to live in a theme file. The update-safe pattern on PrestaShop is to put the markup in an HTML block and the behaviour in your custom JS/CSS files.

1. The markup, via an HTML block

Rather than hard-coding the button into a template, drop it into a content block you control from the back office. There is no built-in back-office page for adding arbitrary scroll-button markup, so use a custom-HTML module that explicitly supports the hook you want, or build a small purpose-built module registered on a known rendered hook. For a footer-anchored button, a hook such as displayFooter or displayBeforeBodyClosingTag is the natural home. We cover the general technique of dropping markup into a supported, rendered hook in HTML blocks: adding custom content anywhere. The button itself is one element:

<button id="scrollTop" aria-label="Scroll to top of page">↑</button>

2. The behaviour, in custom.js (not theme.js)

PrestaShop's classic theme includes a custom.js (and custom.css) so you can add behaviour without touching compiled theme assets, but availability and update behaviour are theme-dependent, and a theme update can overwrite parent-theme files. For reliable update safety, put your JS/CSS in a child theme or a module; only use the parent theme's custom.js/custom.css if you accept reviewing them after each theme update. That is where the scroll logic goes. The reason this is the correct place, and the asset-pipeline caveats around it. Is the whole subject of custom CSS and JavaScript without breaking updates, which is worth reading before you add any front-end script. The logic itself is unremarkable: show the button after the viewport scrolls past roughly 300px, and smooth-scroll to the top on click.

3. The styling, in custom.css

Positioning lives in custom.css: fixed to the bottom-right, a tap target no smaller than 44×44px, and. This is the PrestaShop-specific gotcha. A z-index that sits below your cookie-consent banner and any chat widget but above page content. On a typical store you're competing with the GDPR banner, the live-chat bubble, and, if your theme or a module adds one. A sticky add-to-cart bar on product pages; pick the z-index deliberately rather than reaching for 999999 and hoping.

Native button vs HTML block vs theme edit

ApproachSurvives updates?Where it livesBest when…
Use your theme's own buttonYesTheme (style it in custom.css)Your (usually premium) theme already renders one and it just needs restyling or repositioning.
HTML block + custom.js/custom.cssYesA content block + custom asset filesYour theme has no button, or its button is broken, and you want one with zero theme surgery.
Child-theme overrideYes (until you change theme)themes/your-child-theme/You're already maintaining a child theme for other reasons.
Editing the parent themeNoActive theme's .tpl/.jsNever. The next theme update silently removes it.

The accessibility and z-index details PrestaShop forces on you

Back to Top module back office with enable, scroll threshold, button style and position settings

From the back office you set when the button appears, its style and which corner it sits in, no theme code to touch.

Two things break scroll buttons on real PrestaShop stores, and both are easy to get right once. First, accessibility: render the button as a real <button>, not a styled <div>, give it an aria-label="Scroll to top of page" so a screen reader announces its purpose, and make sure it is reachable by keyboard. An arrow glyph with no label is invisible to assistive technology.

Second, the layering problem. A PrestaShop front office often stacks several fixed elements in the same bottom-right corner, the cookie/consent notice, the chat widget, and, on stores whose theme or a module adds it, a sticky add-to-cart bar that appears on product pages as the customer scrolls (this is not a native PrestaShop feature, so check whether yours has one). A scroll button with a careless z-index will cover the "Add to cart" button, which means your tiny UX improvement is now suppressing orders. Test the button on a product page with a long description specifically, on mobile, with your consent banner showing, before you call it done.

Don't reinvent the smooth scroll if you're already adding motion

If a scroll-to-top button is the only animation you're considering, the lightweight custom-JS route above is the right amount of effort. Anything heavier is over-engineering a single button. But if you're also planning fade-ins, reveal-on-scroll sections, or other movement across your store, it's worth deciding on one consistent approach to scroll behaviour rather than bolting on disconnected scripts that each listen to the same scroll event. We cover doing that tastefully (and without tanking performance) in scroll animations: adding subtle movement.

The short version

On PrestaShop the scroll-to-top button is not a coding problem, the code is five lines, it is a placement problem. Put the markup in a back-office HTML block, the behaviour in custom.js, the styling in custom.css, never in the parent theme, and give it a z-index that respects the consent banner and the add-to-cart bar. Do that and you get the engagement benefit with zero maintenance burden and nothing to re-do at the next update. The hard-won lesson behind all of this is the one running through this whole cluster: the small front-end touches that look trivial are exactly the ones that quietly break on update unless you add them in the place PrestaShop leaves for you.

Frequently asked questions

How do I tell whether my theme already has a scroll-to-top button?

Scroll your homepage and a long category page on both desktop and mobile. If an arrow appears bottom-right and works, your theme provides it. Your job is styling, not building. To confirm where it comes from, view source and search for a #back-to-top or .scroll-to-top element. The default classic theme has none, so on a stock classic store there's genuinely nothing to find.

Because footer.tpl and theme.js are parent-theme files, and the next theme update overwrites them, your button vanishes, usually unnoticed for weeks. It's the single most common way a "tiny" tweak becomes recurring maintenance. Put the markup in a back-office HTML block and the behaviour in custom assets or a module instead, so nothing in the theme tree carries your change.

Which hook should the button's HTML block use?

For a footer-anchored button, displayFooter or displayBeforeBodyClosingTag are the natural homes, both render near the end of the page on a stock store. There's no built-in back-office page for arbitrary scroll-button markup, so use a custom-HTML module that explicitly supports the hook you want, or build a small purpose-built module registered on a known rendered hook.

What z-index should I give it?

One chosen deliberately, not 999999. The button needs to sit above page content but below your cookie-consent banner, your chat widget, and any sticky add-to-cart bar on product pages, otherwise it covers the buy button and suppresses orders. Pick a value, then test on a long product page on mobile with the consent banner showing and the add-to-cart bar live before you call it done.

Does the button need to be keyboard-accessible?

Yes. Render it as a real <button>, not a styled <div>, so it's focusable and reachable by keyboard, and give it an aria-label="Scroll to top of page" so a screen reader announces its purpose. An arrow glyph with no label is invisible to assistive technology, and a div isn't focusable at all. Both are easy to get right at build time and painful to retrofit.

My theme already renders a button. Can I just reposition it?

Yes, and that's a CSS job, not a build. Style and reposition the existing button in custom.css (or your child theme's stylesheet) rather than adding a second one. Two back-to-top buttons stacked in the same corner is a common accidental result of not checking first. Adjust its bottom/right offsets and z-index so it clears your other fixed widgets.

Should I write its own scroll logic if I'm also adding other animations?

If the button is the only motion you're adding, the lightweight custom-JS route is exactly enough. But if you're also planning fade-ins or reveal-on-scroll sections, settle on one consistent scroll approach rather than bolting on disconnected scripts that each listen to the same scroll event, that's how performance quietly degrades. The scroll animations guide covers doing it as one managed layer.

Tags: PrestaShop UX
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