I want to create an unsubscribe option for one category of blogs. i have one category of blogs on a certain topic. i want to send it as an email campaign but with an option for readers to unsubscribe from receiving this category of blogs from me.
I looks like the blog category is not exposed as a condition in the automations, so maybe a custom code solution may work.
Wix’s standard Email Campaign unsubscribe link is site-wide. If a reader uses it, they are marked Unsubscribed and will stop receiving all future marketing campaigns
You can already send a campaign to a contact label instead of your whole list. In the recipients step, under Target group, there’s a + Add Label. So the audience side works today. Make a label for the topic and add the readers who want it, then pick that label as the campaign’s target group.
Nothing built in takes the label back off again. The automation builder can add a label to a contact, but it has no action for removing one, so the opt-out needs a page of your own with a little backend code behind it.
Personalized content only reaches text elements and the subject line, so you can’t carry a contact ID inside the link and have each reader arrive already identified. The page has to ask for the address instead.
This goes in a backend file called backend/email-preferences.web.js:
import { webMethod, Permissions } from 'wix-web-module';
import { contacts, labels } from 'wix-crm.v2';
import { elevate } from 'wix-auth';
// Kept server side so the page can only name a topic, never a label.
const TOPICS = { recipes: 'Weekly recipes' };
const elevatedFindOrCreateLabel = elevate(labels.findOrCreateLabel);
const elevatedQueryContacts = elevate(contacts.queryContacts);
const elevatedUnlabelContact = elevate(contacts.unlabelContact);
export const stopTopic = webMethod(Permissions.Anyone, async (email, topicKey) => {
const displayName = TOPICS[topicKey];
if (!displayName) {
throw new Error('Unknown topic.');
}
const address = String(email || '').trim().toLowerCase();
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(address)) {
throw new Error('That email address does not look valid.');
}
const { label } = await elevatedFindOrCreateLabel(displayName);
const { items } = await elevatedQueryContacts()
.eq('primaryInfo.email', address)
.limit(1)
.find();
if (items.length > 0) {
try {
await elevatedUnlabelContact(items[0]._id, [label.key]);
} catch (error) {
console.error('unlabelContact failed', error);
}
}
return { done: true };
});
The page code calls it, with your own element IDs swapped in:
import { stopTopic } from 'backend/email-preferences.web';
const TOPIC_KEY = 'recipes';
$w.onReady(() => {
$w('#stopButton').onClick(async () => {
$w('#stopButton').disable();
$w('#statusText').text = 'One moment...';
try {
await stopTopic($w('#emailInput').value, TOPIC_KEY);
$w('#statusText').text =
"Done. You won't get that topic again. Everything else carries on as before.";
} catch (error) {
$w('#statusText').text = error.message || 'Something went wrong.';
$w('#stopButton').enable();
}
});
});
The elevate calls are there because unlabelling normally needs Manage Contacts permissions, which a site visitor doesn’t have. The page answers the same way whether or not the address is on your list, so it can’t be used to find out who is subscribed, and it only ever removes a label.
The wording matters as much as the code here. The built-in link is site-wide as Dan_Suhr notes above, and it also can’t be removed or edited, so your topic page sits on top of it rather than replacing it. Wix declines campaigns that “add a second unsubscribe link, or include other unsubscribe options”, so I’d word your link as a topic choice rather than as an unsubscribe, and send a test campaign to yourself before the real one.
I’ve checked this against the current API reference, but I haven’t run it on a live site.