Capture dates with a landing page date picker
Collect a calendar date on a Braze landing page with a native browser date picker, write it to the user profile as a Time custom attribute, and keep known users on one profile with the landing page Liquid tag.
About this example
ClaimsJumpr, a fictional insurance brand, asks consumers to share their policy renewal date on a Braze landing page. Free-text date fields produce inconsistent formats that are hard to segment on. ClaimsJumpr uses a custom form block with an HTML date input so the browser enforces a consistent calendar value. It then writes that value as a Time custom attribute for retargeting.
This scenario combines:
- A Custom Code block on the landing page form
registerFormInput, so the date field validates and submits with the form- The landing page JavaScript bridge, to set a Time custom attribute
- The landing page Liquid tag, so known users stay on one profile
Use it when you need a calendar date on the profile for Time-based segmentation or Canvas timing. Prefer a standard Short Text block when a free-text string is enough.
Considerations
- Short Text form blocks bind only to string custom attributes. To store a date as a Time attribute with date filters (
before,after, andin less than), build a custom form block and callsetCustomUserAttributewith a JavaScriptDate. - Create the custom attribute with the Time data type before you test a submission. Passing a
Datefrom the bridge matches that data type; see Custom attribute data types. - HTML
<input type="date">depends on the visitor’s browser. Support and UI vary by browser and device (for example, some mobile browsers show a native picker; others may fall back to a text-like field). Test on the browsers your audience uses. - Writing custom attributes consumes data points.
- Embed the
{% landing_page_url %}Liquid tag in the message that drives traffic to the page. Without it, submitting the form can create a new anonymous profile instead of updating the known user. - Landing pages with forms need a confirmation experience (confirmation landing page, multi-step confirmation step, or post-submit URL). Plan that before you publish.
- If the page uses a multi-step form, place the Custom Code block that calls
registerFormInputinside the Form layout block so the input participates in form submission. - Test attribute writes and profile linking in a development workspace before you publish to production.
Setup
Step 1: Create a Time custom attribute
- Go to Data Settings > Custom Attributes.
- Create a custom attribute such as
policy_renewal_datewith data type Time. - Use a clear, stable name. Pass the same key to
setCustomUserAttributein the custom form block.
Step 2: Build the landing page form
- Go to Messaging > Landing Pages and create a new landing page.
- Open the drag-and-drop editor and fill in site details (page URL, title, and related settings). See Create landing pages.
- Add the standard form fields you need (for example, a Short Text field for a license plate number bound to a string custom attribute).
- Add a Custom Code block for the renewal date picker. Paste the HTML, script, and styles from Step 3 into that single block.
- Add a submit button that submits the form, and configure your confirmation experience.
- After you’ve finished composition and confirmation, publish the landing page.
Step 3: Register the date picker as a custom form input
Paste the following into one Custom Code (HTML) block. The script registers the date input with registerFormInput, validates that a date is selected, and writes a JavaScript Date to policy_renewal_date on submit.
<div class="renewal-date-field">
<label for="policy-renewal-date">Policy renewal date</label>
<input id="policy-renewal-date" type="date" autocomplete="off" />
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
function parseDateInputValue(value) {
const parts = value.split("-").map(Number);
if (parts.length !== 3 || parts.some((n) => Number.isNaN(n))) {
return null;
}
const [year, month, day] = parts;
// Build a local calendar date so YYYY-MM-DD is not shifted by UTC parsing.
return new Date(year, month - 1, day);
}
window.brazeHelpers.forms.registerFormInput({
selector: "#policy-renewal-date",
isRequired: true,
getValue: (element) => element.value || null,
onValidate: (value) => Boolean(parseDateInputValue(value)),
onSubmit: (value) => {
const date = parseDateInputValue(value);
if (!date) {
return;
}
window.brazeBridge.getUser().setCustomUserAttribute("policy_renewal_date", date);
},
});
});
</script>
<style>
.renewal-date-field {
display: flex;
flex-direction: column;
gap: 8px;
max-width: 280px;
margin: 0 auto;
text-align: left;
}
.renewal-date-field label {
font-weight: 600;
}
/* Braze adds this class to the registered element when validation fails. */
#policy-renewal-date.bz-validation-error {
outline: 3px solid #f94144;
outline-offset: 2px;
border-radius: 4px;
}
</style>
The browser’s date input returns a YYYY-MM-DD string. getValue reads that string, and onValidate confirms it parses. onSubmit converts it to a local Date before calling setCustomUserAttribute. Braze stores that Date as a UTC timestamp without milliseconds. For visitors in time zones ahead of UTC, local midnight can fall on the previous calendar day. Form submission flushes bridge data to Braze after onSubmit completes. Leave requestImmediateDataFlush out of onSubmit.
Replace policy_renewal_date with your Time attribute name from Step 1. Adapt the label and styles to your brand.
Step 4: Link known users from a Braze message
In the email, SMS, or other message that sends consumers to the landing page, insert the landing page Liquid tag so Braze can update the existing profile on submit.
<a href="{% landing_page_url claimsjumpr-renewal-date %}" class="button">Share your renewal date</a>
Replace claimsjumpr-renewal-date with your landing page URL handle. In the message editor, select Personalization, then set Personalization type to Landing Page.
Step 5: Test the attribute write
- Send the message with the landing page Liquid tag to a test user, or open the tagged link from a Braze message.
- Select a renewal date, submit the form, and check that the confirmation experience appears.
- Open the test user’s profile and verify
policy_renewal_dateis set as a Time value. - Optional: build a segment with a Time filter such as
in less thanorin more thanonpolicy_renewal_dateto confirm the attribute is usable for retargeting.