Configurable maxLength for Campaign Title and Description
Configurable maxLength for Campaign Title and Description
ATS partners can now configure the input maxLength for the Campaign Title and Campaign Description fields in the campaign create/edit form. Previously these were hardcoded at 100 and 65,535 characters respectively. Partners with channel-specific UX requirements (for example, a job board that requires shorter titles or descriptions) can now lower the visible limit to comply with those requirements.
What changed
A new formLimits field has been added to the campaign state module. Defaults preserve the previously hardcoded values, so if you don't set formLimits nothing changes for your integration.
window.hapi.state.campaign.formLimits = {
titleMaxLength: number // default: 100
descriptionMaxLength: number // default: 65535
}The Posting Details form's title and description inputs read their maxLength from this state field. Both the runtime SDK setter and the boot-time initialState path are supported (see below).
How to override
There are two ways to set the limits.
Runtime — via the SDK
Mutate the value at any time after window.hapi is ready. The change propagates to all widgets that include the Posting Details form via the existing state subscription mechanism — no widget re-mount required.
window.hapi.state.campaign.formLimits = {
titleMaxLength: 75,
descriptionMaxLength: 5000,
}You can also set only one field; the other keeps its default:
window.hapi.state.campaign.formLimits = {
titleMaxLength: 75,
// descriptionMaxLength omitted — falls back to the default (65535)
}Boot time — via window.hapiConfig.initialState
If you want the limits applied before any widget renders, seed them from window.hapiConfig before the loader script runs. Note the key here is campaignStore (the store name), not campaign — the boot-time initialState shape is keyed by store name, while the runtime SDK setter at window.hapi.state.campaign is keyed by module name. Easy to mix up.
window.hapiConfig = {
// ...your existing config...
initialState: {
campaignStore: {
formLimits: {
titleMaxLength: 75,
descriptionMaxLength: 5000,
},
},
},
}This works on any widget that hosts the campaign form (Order Journey, Order Journey Products, Order Journey Contracts, Order Journey Checkout, or the standalone Posting Details widget).
Caps and clamping
Values are clamped at read time to the existing backend-enforced limits:
| Field | Maximum (cap) |
|---|---|
titleMaxLength | 100 |
descriptionMaxLength | 65,535 |
A higher value passed by an integrator is capped to the maximum, so the FE never advertises a limit the backend would reject. Lower values take effect as supplied. The same value still appears in window.hapi.state.campaign.formLimits when you read it back — only the value the input actually uses is clamped.
Console warning when an override exceeds the cap
To make a clamped override easy to spot during integration, a one-shot console.warn is emitted the first time the SDK sees an over-cap value, per (field, value) pair, per page load:
[HAPI] campaign.formLimits.titleMaxLength=999 exceeds the BE-enforced cap of 100; clamping to 100. Lower your override at or below the cap to silence this warning.- The warning fires once per
(field, value)pair, so MobX-driven re-renders don't flood your DevTools console. - Trying a different over-cap value still warns (e.g. retrying
999 → 500surfaces a fresh warning). - Lowering the value to the cap or below clears it on the next render.
If you do not see this warning in DevTools, your override is being applied as-is.
Other input handling
| Input value | Effective maxLength |
|---|---|
Integer in [1, cap] | Used as supplied |
| Integer above the cap | Cap (with console.warn) |
Fractional (e.g. 50.7, 100 / 3) | Floored to integer (e.g. 50, 33) |
0, negative, or < 1 | 1 (so the input still accepts at least one character) |
NaN, ±Infinity, omitted | Default cap |
Floor-to-integer matters because the HTML maxLength attribute is spec-defined as a non-negative integer; passing a fractional value otherwise lets the browser truncate silently and shows a fractional total in the character counter (e.g. 0 / 33.3).
Notes
- Updates to
campaign.formLimitspropagate to all widgets that include the Posting Details form via the existing state subscription mechanism — no widget-instance reload required. - The
CampaignFormLimitstype is exported from@vonq/hapi-elements-typesfor TypeScript integrations.