diff --git a/apps/api/src/services/ContactService.ts b/apps/api/src/services/ContactService.ts index 35ae603..e3b792d 100644 --- a/apps/api/src/services/ContactService.ts +++ b/apps/api/src/services/ContactService.ts @@ -225,12 +225,14 @@ export class ContactService { // Merge new data (if provided) if (data) { for (const [key, value] of Object.entries(data)) { - // Skip reserved fields - if (key === 'plunk_id' || key === 'plunk_email') { + // Skip reserved system-generated fields + // These fields are dynamically added during template rendering and cannot be overridden + const reservedFields = ['plunk_id', 'plunk_email', 'email', 'unsubscribeUrl', 'subscribeUrl', 'manageUrl']; + if (reservedFields.includes(key)) { continue; } - // Validate locale field + // Validate locale field (special user-settable field) if (key === 'locale') { if (typeof value === 'string') { if (!isValidLanguageCode(value)) { @@ -321,8 +323,9 @@ export class ContactService { // Add temporary (non-persistent) data if (temporaryData) { for (const [key, value] of Object.entries(temporaryData)) { - // Skip reserved fields - if (key === 'plunk_id' || key === 'plunk_email') { + // Skip reserved system-generated fields + const reservedFields = ['plunk_id', 'plunk_email', 'email', 'unsubscribeUrl', 'subscribeUrl', 'manageUrl']; + if (reservedFields.includes(key)) { continue; } diff --git a/apps/wiki/content/docs/concepts/contacts-and-data.mdx b/apps/wiki/content/docs/concepts/contacts-and-data.mdx index c6cbcae..11bb17d 100644 --- a/apps/wiki/content/docs/concepts/contacts-and-data.mdx +++ b/apps/wiki/content/docs/concepts/contacts-and-data.mdx @@ -85,7 +85,14 @@ Use `{{fieldName}}` in emails: **Fallback:** `{{firstName ?? 'there'}}` -**Predefined fields:** `{{email}}`, `{{unsubscribeUrl}}`, `{{subscribeUrl}}`, `{{manageUrl}}`, `{{locale}}` +**System-generated fields (always available):** +- `{{email}}` - Contact's email address +- `{{unsubscribeUrl}}` - Link to unsubscribe page +- `{{subscribeUrl}}` - Link to subscribe page +- `{{manageUrl}}` - Link to preference center + +**Special fields:** +- `{{locale}}` - Contact's language preference (user-settable, overrides project default) ## Temporary data