This Confluence user macro adds a celebratory confetti animation when a page is updated.
It automatically detects if the current page version has changed and, if so, displays a short burst of animated confetti along with a random motivational message.
The macro runs silently in the background, cleans up after itself, and resizes to zero once the animation ends β ensuring minimal layout disruption.
Confetti effects are powered by the open-source canvas-confetti library.
#set($pageId = $page.id)
#set($outputType = $renderContext.outputType)
<div id="page-edit-confetti" data-macro="page-edit-confetti" style="display: none; overflow: hidden; padding: 0; margin: 0;"></div>
<style>
@keyframes fadeOut {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.95);
}
}
.fade-out {
animation: fadeOut 500ms ease-out forwards;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>
<script>
(function () {
const pageId = "$pageId";
const storageKey = "confluence-page-version-" + pageId;
const confettiDuration = 3500;
const fadeDuration = 500;
const confettiBox = document.getElementById("page-edit-confetti");
const outputType = "$outputType";
const messages = [
"π Another page powered up! Your contribution just made the workspace smarter.",
"π Update complete! Thanks for keeping the team in the loop!",
"π Way to go! Youβve just made collaboration a little easier for everyone.",
"π Nice update! Great documentation is what drives great teams.",
"π‘ Content refreshed! Thanks for keeping knowledge flowing.",
"π Knowledge champion alert! Your update keeps us all moving forward.",
"π Sync complete! This kind of effort is what makes teamwork work.",
"π₯ Update magic! Youβve added real valueβthanks for keeping things sharp.",
"π Documentation wizardry! A small update, a big impact.",
"π₯³ Celebrate that save! Another step toward a more organized, efficient team."
];
if (!confettiBox || typeof AP === "undefined") return;
if (outputType === "preview") {
confettiBox.style.display = "none";
confettiBox.style.height = "0px";
AP.resize("0px", "0px");
setTimeout(() => AP.resize("0px", "0px"), 100);
return
}
confettiBox.style.display = "none";
confettiBox.style.height = "0px";
confettiBox.innerHTML = "";
AP.resize("0px", "0px");
AP.request({
url: "/api/v2/pages/" + pageId + "/versions",
type: "GET",
success: function (responseText) {
try {
const data = JSON.parse(responseText);
const currentVersion = data.results?.[0]?.number;
if (!currentVersion) return;
const storedVersion = parseInt(localStorage.getItem(storageKey), 10);
const isNew = !storedVersion || currentVersion > storedVersion;
if (isNew) {
localStorage.setItem(storageKey, currentVersion.toString());
const message = messages[Math.floor(Math.random() * messages.length)];
confettiBox.innerHTML =
'<div id="confetti-msg" style="' +
'text-align: center;' +
'color: #ff4081;' +
'font-size: 1.8rem;' +
'font-weight: bold;' +
'padding: 2rem 1rem;' +
'font-family: -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;' +
'">' +
message +
'</div>';
confettiBox.style.display = "block";
confettiBox.style.height = "500px";
AP.resize("100%", "500px");
if (window.confetti) {
window.confetti({
particleCount: 200,
spread: 70,
origin: {
y: 0.6
}
});
}
setTimeout(() => {
const msg = document.getElementById("confetti-msg");
if (msg) {
msg.classList.add("fade-out");
}
setTimeout(() => {
confettiBox.innerHTML = "";
confettiBox.style.display = "none";
confettiBox.style.height = "0px";
AP.resize("0px", "0px");
setTimeout(() => AP.resize("0px", "0px"), 100);
}, fadeDuration);
},
confettiDuration);
} else {
confettiBox.innerHTML = "";
confettiBox.style.display = "none";
confettiBox.style.height = "0px";
AP.resize("0px", "0px");
setTimeout(() => AP.resize("0px", "0px"), 100);
}
} catch (e) {
console.error("Failed to parse version response:",
e);
}
},
error: function (err) {
console.error("API request failed:",
err);
}
});
})();
</script>Generate a list of all the content created by a current user by default or a specified user across your Confluence site.
Retrieve and display current exchange rates for major currencies against a specified base currency.
Create dropdown menus in Confluence Cloud with predefined sets of options, multiselect features, and permission gates
Shows page creation date
Get the latest cryptocurrency rates for major coins.
Display a custom list of recently updated content
Perform customized searches based on labels, content types, and other parameters.
Convert a specified amount of cryptocurrency to fiat currency.
Shows all attachments from the current space in a table view
The content of this macro will not go to the printing page