# DF Recently Viewed — Recently viewed products (PrestaShop 8/9)

> Overview DF Recently Viewed (dfrecentlyviewed) displays the products your visitors have recently viewed, but with an architecture designed for conversion: history is stored server-side, merged into the customer account at…

- Page: <https://www.datafirefly.com/en/documentation/dfrecentlyviewed/>
- Language: en
- Last updated: 2026-07-12
- Other languages: [fr](https://www.datafirefly.com/documentation/dfrecentlyviewed/index.md), [es](https://www.datafirefly.com/es/documentation/dfrecentlyviewed/index.md), [de](https://www.datafirefly.com/de/documentation/dfrecentlyviewed/index.md), [it](https://www.datafirefly.com/it/documentation/dfrecentlyviewed/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfrecentlyviewed/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfrecentlyviewed/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfrecentlyviewed/index.md)
- Index: <https://www.datafirefly.com/en/documentation/llms.txt>

## Overview

DF Recently Viewed (`dfrecentlyviewed`) displays the products your visitors have recently viewed, but with an architecture designed for conversion: history is stored server-side, merged into the customer account at login, rendered via AJAX so it stays accurate behind a page cache, and enriched with price-drop badges. An analytics dashboard completes the picture with a view-to-purchase conversion rate.

### Requirements

- PrestaShop 8.0 to 9.x
- PHP 7.4 to 8.3
- No external dependency (no Composer, no jQuery, no carousel library)

## Installation

1. In the back office, open **Modules > Module Manager**.
2. Click **Upload a module** and drop the `dfrecentlyviewed.zip` file.
3. Click **Install**. The module creates its table, registers its hooks and adds a **Catalog > Recently Viewed Stats** tab.
4. Click **Configure** to access the settings.

The module works out of the box with sensible defaults: 8 products, carousel, AJAX rendering, price-drop badges enabled, 90-day retention.

## Configuration

### Display tab

- **Block title** — translatable in each of your languages.
- **Number of products** — from 1 to 24 products displayed in the block.
- **Carousel layout** — enabled: horizontal carousel with navigation arrows. Disabled: responsive grid.
- **Show on product pages** — `displayFooterProduct` hook.
- **Show on homepage** — `displayHome` hook.
- **Show on cart page** — `displayShoppingCartFooter` hook.
- **Show "clear my history" link** — recommended for GDPR transparency.

### Smart behavior tab

- **Exclude the product currently displayed** — avoids recommending the page already on screen.
- **Hide out-of-stock products** — the filter accounts for allowed backorders.
- **Hide products already in the cart** — the cart is recalculated server-side, never from the cached page.
- **Price-drop badges** — displays a "-X%" badge when the price has dropped since the visitor last viewed the product.
- **AJAX rendering (cache-safe)** — strongly recommended, see the dedicated section below.
- **History retention (days)** — from 1 to 730 days. Older views are purged automatically.

## Full-page-cache compatibility

On a shop running Varnish, Cloudflare, LiteSpeed Cache or a CDN, a personalised block rendered server-side gets cached along with the page: the next visitor sees someone else's history, or an empty block.

The **AJAX rendering** mode, enabled by default, solves this: the block is injected after the page renders, through a request to the module's front controller. Product view tracking is sent as a non-blocking _beacon_, which also works when the page comes from cache.

Only disable AJAX mode if your shop uses no page cache at all. Otherwise the block will display incorrect data.

## Price-drop badges

Every time a product page is viewed, the module stores the tax-included price shown at that moment for that specific visitor. When the block is displayed, it compares that remembered price with the current one:

- If the price dropped by at least 1%, a red "↓ -X%" badge appears in the top-left corner of the miniature.
- The remembered price is updated on each new view: the badge therefore always means "the price has dropped since your last visit to this page".
- If the price goes back up, the badge disappears.

## Cross-device history

Views are recorded with the guest identifier (`id_guest`) for anonymous visitors, and with the customer identifier (`id_customer`) for logged-in visitors.

At login (`actionAuthentication` hook), the guest history is merged into the customer account: view counters are summed and the most recent view date is kept. The customer thus finds their viewed products on every device.

## "My browsing history" page

The module adds a tile in the customer account (`displayCustomerAccount` hook) leading to a dedicated page showing up to 48 viewed products, with a clear button if the option is enabled.

Page URL: `/module/dfrecentlyviewed/history` (rewritten according to your URL configuration).

## Widget

The block can be called from any template in your theme:

```
{widget name='dfrecentlyviewed'}
{widget name='dfrecentlyviewed' limit=6}
```

The `limit` parameter is optional and capped at 24; without it, the number configured in the back office applies.

## Analytics dashboard

Go to **Catalog > Recently Viewed Stats**. Over a period of 7, 30, 90 or 365 days you will find:

- **Product views** — total number of recorded views.
- **Distinct products viewed** — the real breadth of catalog discovery.
- **Unique visitors** — guests and customers combined.
- **View-to-purchase conversion** — percentage of viewed customer/product pairs that led to a valid order placed after the view. Computed on logged-in customers only.
- **Most viewed products** — ranking with a direct link to the product page in the back office.

## GDPR and retention

### psgdpr hooks

The module implements `actionExportGDPRData` and `actionDeleteGDPRCustomer`: if the official psgdpr module is installed, browsing history is included in the personal data exports and deletions requested by your customers.

### Self-service clearing

When the option is enabled, a "Clear my history" link appears next to the block title and on the history page. Visitors can delete their own data, with confirmation.

### Automatic purge

Views older than the configured retention period are purged automatically, opportunistically (on roughly 1% of recorded views). No configuration is needed.

### Optional CRON

For high-traffic shops, a token-protected purge URL is shown on the configuration page. You can call it daily:

```
0 4 * * * curl -s "https://your-shop.com/module/dfrecentlyviewed/tracking?action=cleanup&token=YOUR_TOKEN"
```

## Theme integration

Products are rendered through your theme's native miniature (`catalog/_partials/miniatures/product.tpl`). The block therefore automatically inherits your listing design: image, name, price, promotion badges, quick-add button if your theme provides one.

If you want to customise the container, override the module templates from your theme:

```
themes/your-theme/modules/dfrecentlyviewed/views/templates/hook/recentlyviewed.tpl
themes/your-theme/modules/dfrecentlyviewed/views/templates/hook/_products.tpl
```

## Multistore

Histories are isolated per shop: a visitor viewing a product on shop A will not see it appear on shop B. All settings are stored through PrestaShop's Configuration table, with native multistore support.

## Uninstalling

Uninstalling removes the history table, all settings and the statistics tab. A confirmation is requested before the operation.

## Troubleshooting

### The block does not appear

- Check that the hook matching the page is enabled in the configuration (product page, homepage, cart).
- The block only appears if the visitor has viewed at least one eligible product. A first-time visitor will see nothing.
- If both current-product exclusion and cart exclusion are active, it is possible that no product remains to display.

### The block stays empty on a cached page

Make sure **AJAX rendering** is enabled. Also check that your cache configuration does not intercept requests to `/module/dfrecentlyviewed/tracking`.

### Price-drop badges never appear

The badge can only appear if the visitor viewed the product _before_ the price drop. After changing a price, give visitors time to come back. Also check that the option is enabled.
