<p>You can store the ID of entries you've already displayed to this user in the <a href="https://docs.craftcms.com/api/v4/craft-web-session.html" rel="nofollow noreferrer">session</a>, then use <code>.id(['not', 1, 2])</code> to <a href="https://craftcms.com/docs/4.x/entries.html#id" rel="nofollow noreferrer">exclude those entries</a> on later request. On each page load, add the randomly selected entry to the list of ads already displayed. When all ads have been shown, maybe clear the list and start anew.</p>
<p>However, this presents several problems. Every time randomness and state are involved, you severely limit your ability to cache effectively. If you cache a random result, it won't look so random any more, and if the output of a template depends on values in the session, you can't cache that output at all.</p>
<p>I would recommend building this in a way that allows the output to be cached. For example:</p>
<ul>
<li>Query and output <em>all</em> ads with the <code>[hidden]</code> attribute, then use JavaScript to randomly toggle one of them.</li>
<li>Create a controller that returns data for a random ad, then <code>fetch()</code> and insert it using JavaScript in the frontend.</li>
</ul>
<p>In both cases, you can use the same logic to exclude ads you've already shown. If you store the list in <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" rel="nofollow noreferrer"><code>localStorage</code></a>, you can even avoid repeated ads across browser sessions.</p>
<p>Of course, using JavaScript means the ad might display with a slight delay and might negatively impact your <a href="https://web.dev/cls/" rel="nofollow noreferrer">CLS score</a>.</p>

CC BY-SA 4.0
2023-02-10T11:36:24.100Z
2023-02-10T11:36:24.100Z
MoritzLost
<p>The easiest way to get a entries sort by random is to apply this: <code>.orderBy('RAND()')</code>.</p>
<p>This is very useful, however I have a case where I need to get entries (which are adverts) in a random sequence which should go forward at each reload or at least present a different equitable result at each reload.</p>
<p>Considering these entries: <code>A, B, C</code>. I could get this on first load (first random result): <code>C, B, A</code>. Then on first next reload (other random, but try to follow sequence to prevent duplicated display): <code>A, C, B</code> ← not <code>C, B, A</code>.</p>
<p>When finished all unique combinations possible, restart a random sequence.</p>
<p>What would be the best solution?</p>

<entries><order><random>
Get random entries order at each page load, but avoid repetitions
# Get random entries order at each page load, but avoid repetitions

(Asked by: username_0 on 2023-02-09)

The easiest way to get a entries sort by random is to apply this: `.orderBy('RAND()')`.

This is very useful, however I have a case where I need to get entries (which are adverts) in a random sequence which should go forward at each reload or at least present a different equitable result at each reload.

Considering these entries: `A, B, C`. I could get this on first load (first random result): `C, B, A`. Then on first next reload (other random, but try to follow sequence to prevent duplicated display): `A, C, B` ← not `C, B, A`.

When finished all unique combinations possible, restart a random sequence.

What would be the best solution?

**Tags:** entries, order, random


---

## 1 answers

### Answer by username_1 on 2023-02-10. Score: 1 | Accepted answer

You can store the ID of entries you've already displayed to this user in the [session](https://docs.craftcms.com/api/v4/craft-web-session.html), then use `.id(['not', 1, 2])` to [exclude those entries](https://craftcms.com/docs/4.x/entries.html#id) on later request. On each page load, add the randomly selected entry to the list of ads already displayed. When all ads have been shown, maybe clear the list and start anew.

However, this presents several problems. Every time randomness and state are involved, you severely limit your ability to cache effectively. If you cache a random result, it won't look so random any more, and if the output of a template depends on values in the session, you can't cache that output at all.

I would recommend building this in a way that allows the output to be cached. For example:

* Query and output *all* ads with the `[hidden]` attribute, then use JavaScript to randomly toggle one of them.
* Create a controller that returns data for a random ad, then `fetch()` and insert it using JavaScript in the frontend.

In both cases, you can use the same logic to exclude ads you've already shown. If you store the list in [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), you can even avoid repeated ads across browser sessions.

Of course, using JavaScript means the ad might display with a slight delay and might negatively impact your [CLS score](https://web.dev/cls/).


---

