While working with Dynamics 365 Customer Insights – Journeys Real-time Marketing Forms, we wanted to explore a simple way of reducing bot submissions.
A common technique used on websites is a honeypot. The idea is straightforward:
- Add a field that genuine users never see.
- Hide it using JavaScript.
- If the field contains a value when the form is submitted, assume it was completed by a bot and cancel the submission.
In this post, we’ll implement this using the supported Client-side Extensibility events provided by Dynamics 365.
Step 1: Add an Unbound Field
Add a new Short Text field to the form.
The field can be Unbound, as it is only used for validation and does not need to be stored in Dataverse.
We used hp_check for the field name as this avoids browser autofill heuristics that may populate well-known fields such as Middle Name, Email, or Phone.

Step 2: Hide the Field
The field should remain in the HTML so that automated bots can still discover it, but it should not be visible to genuine users.
In our implementation, the field is hidden using CSS, which avoids any brief flicker that could occur if it were hidden only after the form loads.
.textFormFieldBlock:has(input[name="hp_check"]) {
position: absolute !important;
left: -9999px !important;
width: 1px !important;
height: 1px !important;
overflow: hidden !important;
}
Step 3: Validate During Form Submission
Using the supported d365mkt-afterformload and d365mkt-formsubmit events, configure the field and validate it before submission.
<script>
let honeypotField = null;
document.addEventListener("d365mkt-afterformload", function () {
honeypotField = document.querySelector('[name="hp_check"]');
if (!honeypotField) {
return;
}
honeypotField.setAttribute("autocomplete", "off");
honeypotField.setAttribute("tabindex", "-1");
honeypotField.setAttribute("aria-hidden", "true");
});
document.addEventListener("d365mkt-formsubmit", function (event) {
if (honeypotField && honeypotField.value.trim() !== "") {
event.preventDefault();
}
});
</script>
The d365mkt-formsubmit event is cancelable, so calling event.preventDefault() prevents the form from being submitted.
Testing
To test the implementation, we opened the browser Developer Tools and executed the following in the Console:
document.querySelector('[name="hp_check"]').value = "I am a bot";
When we clicked Submit, the d365mkt-formsubmit event was triggered and event.preventDefault() successfully cancelled the submission.
Things to consider
While implementing this, there were a few considerations that helped improve the solution:
- Use a neutral field name such as hp_check instead of generic field name to reduce the chance of browser autofill populating the field.
- Hide the field using CSS instead of JavaScript to avoid a brief flash of the field while the page is loading.
- Keep the field unbound, as it is only used for validation.
- A client-side honeypot helps reduce spam submissions, but it should be considered one layer of protection. For higher security requirements, additional server-side validation can also be implemented. For e.g. if it is bound field on lead than a plugin on pre create operation or if it is unbound we can have plugin against Form Submission table.
Conclusion
A honeypot is a simple but effective technique for reducing automated submissions to Dynamics 365 Customer Insights – Journeys Real-time Marketing Forms.
By using the supported Client-side Extensibility events, the implementation remains lightweight, requires no Dataverse customizations, and can be easily reused across multiple for
References
Real-time Marketing Form Client-side Extensibility
Hope it helps..
Discover more from Nishant Rana's Weblog
Subscribe to get the latest posts sent to your email.
