This Script Pre-Populates ConvertKit Landing Pages with a known subscriber's First Name and Email. There are multiple reasons to pre-populate a form, but the driving need is to reduce friction to increase opt-in rates. Use this when doing a partner promo or even just segmenting your own subscribers into a new segment for a promotion, webinar, or product launch etc.
- Easy Integration: Drop-in script for ConvertKit landing pages
- Input Validation: Email format validation and XSS protection
- Security: Automatic input sanitization to prevent malicious code injection
- Configuration: Customize field mappings, validation rules, and behavior
- Error Handling: Robust error handling with optional debug mode
- Callbacks: Success/error callbacks for custom logic
- Backwards Compatible: Works with existing implementations
To use this script on your pages, add this script to your opt-in page. In ConvertKit, add the HTML Block element to your page. You'll need to wrap the code in script tags as shown below.
<script src="path/to/pre-pop.js"></script>That's it! The script will automatically populate form fields from URL parameters fn (first name) and em (email).
For more control, you can configure CKPrePop with custom options:
<script src="path/to/pre-pop.js"></script>
<script>
CKPrePop.init({
// Custom field mappings
fields: {
fn: 'fields[first_name]',
ln: 'fields[last_name]', // Add last name
em: 'email_address',
ph: 'fields[phone_number]' // Add phone
},
// Validation settings
validation: {
enabled: true,
maxLength: 255,
allowedEmailDomains: ['example.com', 'company.com'], // Optional whitelist
sanitizeInput: true
},
// Enable debug mode for development
debug: true,
// Clear fields on error
clearOnError: false,
// Success callback
onSuccess: function(data) {
console.log('Pre-populated:', data);
// Send analytics event, etc.
},
// Error callback
onError: function(error) {
console.error('Error:', error.message);
},
// Validation error callback
onValidationError: function(error) {
console.warn('Invalid input:', error.param, error.message);
}
});
</script>Map URL parameters to form field names. Default:
{
fn: 'fields[first_name]',
em: 'email_address'
}Control validation behavior:
enabled(Boolean): Enable/disable validation. Default:truemaxLength(Number): Maximum input length. Default:255allowedEmailDomains(Array): Whitelist email domains. Empty = allow all. Default:[]sanitizeInput(Boolean): Sanitize inputs to prevent XSS. Default:true
Enable console logging for debugging. Default: false
Clear form fields if an error occurs. Default: false
onSuccess(data): Called when fields are successfully populatedonError(error): Called on general errorsonValidationError(error): Called when validation fails
All inputs are automatically sanitized to prevent cross-site scripting attacks. The following characters are escaped:
<→<>→>"→"'→'/→/
Email addresses are validated using basic format checking (must contain @ and a domain with .) before being set in the form. This catches most common errors while remaining permissive for edge cases.
Inputs exceeding maxLength (default 255 characters) are rejected to prevent buffer overflow attempts.
Optionally restrict email addresses to specific domains:
CKPrePop.init({
validation: {
allowedEmailDomains: ['yourdomain.com', 'partner.com']
}
});Next format your landing page url with fn and em url variables on your ConvertKit Landing page url
So for example if your ConvertKit url is:
https://your-ck-landingpageurl.ck.page/12345678
The template for pre-population would be:
https://your-ck-landingpageurl.ck.page/12345678?fn={{ subscriber.first_name }}&em={{ subscriber.email_address }}
Once processed, the link will look something like this for someone with a first name of "James" and an email address of "james@smith.emailaddress"
https://your-ck-landingpageurl.ck.page/12345678?fn=James&em=james@smith.emailaddress
This link can also me used by partners with other esps to send you traffic. Most Email Service Providers have Tags to dynamically insert a user's first name and email into the url for pre-population, here are some examples from other major email providers.
https://your-ck-landingpageurl.ck.page/12345678?fn=*|FNAME|*&em=*|EMAIL|*
https://your-ck-landingpageurl.ck.page/12345678?fn=~Contact.FirstName~&em=~Contact.Email~
https://your-ck-landingpageurl.ck.page/12345678?fn={{ subscriber.first_name }}&em={{ subscriber.email }}
https://your-ck-landingpageurl.ck.page/12345678?fn={{ subscriber.first_name }}&em={{ subscriber.email }}
https://your-ck-landingpageurl.ck.page/12345678?fn=%FIRSTNAME%&em=%EMAIL%
https://your-ck-landingpageurl.ck.page/12345678?fn={$name}&em={$email}
https://your-ck-landingpageurl.ck.page/12345678?fn=[Name]&em=[Email]
https://your-ck-landingpageurl.ck.page/12345678?fn=[[firstname]]&em=[[email]]
https://your-ck-landingpageurl.ck.page/12345678?fn=[firstname]&em=[email]
If you prefer to paste the script directly into ConvertKit's HTML Block instead of hosting it externally:
<script>
(function(){const u=new URLSearchParams(location.search);for(let[n,v]of u){const f=document.getElementsByName(n.toLowerCase()==='fn'?'fields[first_name]':n.toLowerCase()==='em'?'email_address':null)[0];if(f)f.value=v||'';}})();
</script>Copy the entire contents of pre-pop.js and wrap it in <script> tags:
<script>
// Paste the entire pre-pop.js contents here
</script>
<!-- Optional: Custom configuration -->
<script>
CKPrePop.init({
debug: true,
onSuccess: function(data) {
// Track in analytics
if (window.gtag) {
gtag('event', 'form_prepopulated', {
fields: Object.keys(data).join(',')
});
}
}
});
</script><!-- In ConvertKit HTML Block -->
<script src="https://yourdomain.com/pre-pop.js"></script>URL: https://your-page.ck.page/abc?fn=John&em=john@example.com
<script src="https://yourdomain.com/pre-pop.js"></script>
<script>
CKPrePop.init({
debug: true // See console logs during development
});
</script><script src="https://yourdomain.com/pre-pop.js"></script>
<script>
CKPrePop.init({
fields: {
fn: 'fields[first_name]',
ln: 'fields[last_name]',
em: 'email_address',
co: 'fields[company]'
},
onSuccess: function(data) {
// Send to Google Analytics
if (window.gtag) {
gtag('event', 'prepopulated', {
event_category: 'form',
event_label: 'fields_populated'
});
}
}
});
</script>URL: https://your-page.ck.page/abc?fn=John&ln=Doe&em=john@example.com&co=Acme
<script src="https://yourdomain.com/pre-pop.js"></script>
<script>
CKPrePop.init({
validation: {
allowedEmailDomains: ['company.com', 'partner.com']
},
onValidationError: function(error) {
alert('Only company.com and partner.com emails are allowed');
}
});
</script>If you're upgrading from the basic version, the new version is 100% backwards compatible. Simply replace your script and it will work exactly as before.
To take advantage of new features, optionally add configuration:
// Old version - still works!
// No changes needed
// New version - add features as needed
CKPrePop.init({
debug: true, // Start with debug to see what's happening
validation: {
enabled: true // Enable security features
}
});To create a minified version for production use:
npm run minifyThis uses terser via npx (no installation required) to create a compressed version that's ~72% smaller than the original.
To see compression stats:
npm run minify:statsRun syntax validation:
npm testOpen test.html in a browser to interactively test the pre-population functionality.
- Chrome/Edge: Full support
- Firefox: Full support
- Safari: Full support
- IE11: Partial support (URLSearchParams polyfill recommended)
- Enable debug mode:
CKPrePop.init({ debug: true }) - Check browser console for errors
- Verify URL parameters are present in the URL
- Ensure field names match ConvertKit's form field names
- Check email format is valid (has
@and domain) - If using
allowedEmailDomains, verify domain is in whitelist - Check console for validation error details
If you need to allow special characters:
CKPrePop.init({
validation: {
sanitizeInput: false // Disable XSS protection (not recommended)
}
});MIT License - Copyright (c) 2022 tracking202