By default, Elementor doesn’t give you much control over what happens when a Loop widget has no posts. You’re stuck with the basic “nothing found” message and that’s it.
This snippet fills that gap.
It lets you design your own custom empty state using the Elementor editor and place it anywhere below the Loop widget. When the loop has no posts, whether on page load or after using taxonomy or filter widgets, the Loop widget is automatically hidden and your custom empty state is shown instead.
The snippet simply watches for built-in empty-state marker, the .e-loop-nothing-found-message class, which Elementor outputs whenever a Loop widget has no posts.
On the live site, the empty state only appears when it’s actually needed. Inside the Elementor editor, the logic is turned off, so nothing gets hidden while you’re designing.
Copy & paste the scripts before the </body> tag of your project. If you added them before for another setup, skip this step.
Right-click in Elementor, choose “Paste from another site,” and while the popup is open, press cmd/ctrl + v to insert the layout.
Place the code in an HTML widget or add it through Elementor → Custom Code (before the closing </body> tag) either globally or only on selected pages.
Paste the code through the page or site settings, or add it via Elementor → Custom Code (before </body>) for broader use.
body:not(.elementor-editor-active)
[ou-loop-hide-empty]:has(.e-loop-nothing-found-message) {
display: none !important;
}
body:not(.elementor-editor-active)
[ou-loop-empty-state] {
display: none;
}Paste the script through Elementor → Custom Code (set to load after </body>) for site-wide or page-specific loading.
document.addEventListener("DOMContentLoaded", () => {
if (document.body.classList.contains("elementor-editor-active")) return;
const loops = document.querySelectorAll("[ou-loop-hide-empty]");
const emptyStates = document.querySelectorAll("[ou-loop-empty-state]");
const updateState = () => {
loops.forEach(loop => {
const isEmpty = loop.querySelector(".e-loop-nothing-found-message");
emptyStates.forEach(state => {
if (isEmpty) {
state.classList.add("ou-loop-empty-visible");
} else {
state.classList.remove("ou-loop-empty-visible");
}
});
});
};
updateState();
const observer = new MutationObserver(updateState);
loops.forEach(loop => {
observer.observe(loop, {
childList: true,
subtree: true
});
});
});Place the PHP snippet inside your theme’s functions.php or using any code snippet to enable logic.
Add the attribute ou-loop-hide-empty to the Loop widget itself. This controls hiding the Loop widget when it has no posts.
Add the attribute ou-loop-empty-state to the element you want to show as the empty state. This element remains hidden by default.