Hi,
I created a quiz flow with HTML code inside an iframe. I want to save some information I received from the customer to the contact list, but I can’t save the custom fields I created myself, except for the name and email. Help me please.
You already established the communication between your iFrame and your wix-page?
Yes, I can save the name and email information.
The following steps done already …???
- Go to your Wix Dashboard → Contacts → Contact List
- Click the Settings (
) icon → Contact Fields
- Click + Add Custom Field → give it a name like:
- “Company”
- “Message”
- “Project Type”
- Choose the correct field type (Text, Number, Date, etc.)
- Click Save
This step creates a field key (like
company,message, etc.) in the contact schema.
This is just a quick-shot code-skeletton.
Edit it for your own demands…
BACKEND:
import { contacts } from 'wix-crm-backend';
import { triggeredEmails } from 'wix-crm-backend'; // optional if you want notifications
export function saveContact(name, email, phone, company, message) {
const contactInfo = {
info: {
name: name,
emails: [email],
phones: [phone],
// custom fields go here:
company: company,
message: message
}
};
return contacts.saveContact(contactInfo)
.then((contact) => {
console.log("Contact saved:", contact);
return contact;
})
.catch((err) => {
console.error("Error saving contact:", err);
});
}
FRONTEND:
import { saveContact } from 'backend/contactManager'; // adjust to your backend file name
export function submitButton_click(event) {
const name = $w('#nameInput').value;
const email = $w('#emailInput').value;
const phone = $w('#phoneInput').value;
const company = $w('#companyInput').value;
const message = $w('#messageInput').value;
saveContact(name, email, phone, company, message)
.then(() => {
$w('#successMessage').show();
})
.catch((err) => {
console.log(err);
});
}
Another option…
BACKEND:
// Use the new v2 API
import { contacts } from 'wix-crm.v2';
export async function saveContact(name, email, phone, company, message) {
try {
const contactInfo = {
info: {
name,
emails: [email],
phones: [phone],
// use exact custom field keys from your Contact Settings:
'custom.company': company,
'custom.message': message
}
};
// createContact() is the correct function in wix-crm.v2
const contact = await contacts.createContact(contactInfo);
console.log("Contact created:", contact);
return contact;
} catch (err) {
console.error("Error creating contact:", err);
throw err;
}
}
FRONTEND:
import { saveContact } from 'backend/contactManager.jsw';
export function submitButton_click(event) {
const name = $w('#nameInput').value;
const email = $w('#emailInput').value;
const phone = $w('#phoneInput').value;
const company = $w('#companyInput').value;
const message = $w('#messageInput').value;
saveContact(name, email, phone, company, message)
.then(() => {
$w('#successMessage').show();
console.log("Contact saved successfully!");
})
.catch((err) => {
console.error("Error:", err);
$w('#errorMessage').show();
});
}
If still not working ---> https://dev.wix.com/docs/velo/apis/wix-crm-v2/contacts/contacts/introduction
ANOTHER OPTION… —> Members Custom Fields Introduction | SDK
And once uppon a time, there have been → Wix-Contacts-Backend / Frontend
Older APIs and other modules
- The module
wix-crm-backend(orwix-crm-backend) is an older backend‐only version of the CRM APIs. dev.wix.com+1 - There’s also mention of
wix-crmwithout the.v2, which corresponds to version 1 modules. The general API versioning guideline says: modules with.v2or higher are “universal modules” vs older ones. dev.wix.com+1 - Some documentation may call reference to
wix-contacts-backendor similar — but I could not find a current official module by that exact name in the current docs, so it likely is deprecated or renamed. - In short: If you pick the older module (version 1) it can still work (Wix often keeps older versions available) but you’ll miss newer features and might run into limitations or deprecation eventually.
—> but these days maybe already to old and DEPRICATED since i can’t find it anymore inside of the Wix-APIs
If it would be me, i would have something similar like the following in my FRONTEND-FILE…
import { saveContact } from 'backend/contactManager.jsw';
$w.onReady(() => {console.log('Page is ready...');
// Button click handler
$w('#MySubmitButtonIdHere').onClick(async (e) => {console.log(`${e.target.id} clicked`);
// Read input values **at the moment of click**
const name = $w('#nameInput').value; console.log(`Name: ${name} defined...`);
const email = $w('#emailInput').value; console.log(`Email: ${email} defined...`);
const phone = $w('#phoneInput').value; console.log(`Phone: ${phone} defined...`);
const company = $w('#companyInput').value; console.log(`Company: ${company} defined...`);
const message = $w('#messageInput').value; console.log(`Message: ${message} defined...`);
// Call backend to save contact
try {
await saveContact(name, email, phone, company, message); console.log('Contact saved successfully...');
$w('#successMessage').show();
} catch (err) {console.error('Error saving contact:', err);}
});
});
…or using a reusable function like…
import { saveContact } from 'backend/contactManager.jsw';
$w.onReady(() => {
console.log('Page is ready...');
// Button click handler
$w('#MySubmitButtonIdHere').onClick(async (e) => {
console.log(`${e.target.id} clicked`);
// Read input values **at the moment of click**
const name = $w('#nameInput').value;
console.log(`Name: ${name} defined...`);
const email = $w('#emailInput').value;
console.log(`Email: ${email} defined...`);
const phone = $w('#phoneInput').value;
console.log(`Phone: ${phone} defined...`);
const company = $w('#companyInput').value;
console.log(`Company: ${company} defined...`);
const message = $w('#messageInput').value;
console.log(`Message: ${message} defined...`);
// Call reusable save function
try {
await save_CONTACTS(name, email, phone, company, message);
console.log('Contact saved successfully...');
$w('#successMessage').show();
} catch (err) {
console.error('Error saving contact:', err);
}
});
});
// Reusable function that returns a promise
function save_CONTACTS(name, email, phone, company, message) {
console.log('Calling save_CONTACTS function...');
return saveContact(name, email, phone, company, message)
.then(() => {
console.log('Backend saveContact completed successfully.');
})
.catch((err) => {
console.error('Error inside save_CONTACTS:', err);
throw err; // re-throw to propagate to click handler
});
}
And some additional informations about the backend-JSW-Files…
But since JSW-Files also seems to depricated already → OH MY!!! EVERYTIME YOU HAVE TO SWITCH TO SOMETHING NEW → NO CONSTANT CODING WORLD ← → so you have now to use —>
Transitioning from .jsw to .web.js
1. New File Structure
.web.js: This is the new standard for backend modules that can be called from the frontend. It allows you to define web methods with explicit permissions and supports modern JavaScript features..js: Used for internal backend logic that isn’t exposed to the frontend.
2. Defining Web Methods
In the new system, you define web methods using the webMethod function from the wix-web-module package. Here’s how you can define a simple web method:
// backend/myModule.web.js
import { webMethod } from 'wix-web-module';
export const myFunction = webMethod(async (request) => {
// Your backend logic here
return { message: 'Hello from the backend!' };
});
3. Setting Permissions
Permissions are now set directly within the webMethod definition. This allows for more granular control over who can access your backend functions:
import { webMethod, Permissions } from 'wix-web-module';
export const saveContact = webMethod(Permissions.SiteMember, async (name, email) => {
// Save contact logic
return { success: true };
});
In this example, only site members can call the saveContact function.
4. Calling Backend Functions from the Frontend
To call these backend functions from your frontend code, you import them as follows:
// frontend code
import { saveContact } from 'backend/myModule.web.js';
$w.onReady(() => {
$w('#submitButton').onClick(async () => {
const response = await saveContact('John Doe', 'john@example.com');
console.log(response.message);
});
});
Now you should have enough INFORMATIONS to resolve your issue !!!
But wait!!! Let’s do the → TIME-JUMP ←

And here your ADVENTURE into the → PAST <—
- You loved my → POST ←
- It did help you to find your solution ???
- Or should i go → COMMERCIAL ← next time with my reply? xDDDDD
Where are all of those → ![]()
![]()
![]()
![]()
![]()
???

