Contact Form 7 Plugin Setup for WordPress
Contact Form 7 is the most popular free forms plugin for WordPress, installed on tens of millions of sites. It is minimalist: doesn't store submissions in the database by default, has no visual editor — only shortcodes and hooks. For simple contact forms, this is sufficient.
Creating a Form
After installation: Contacts → Add. Form is created via simple shortcode syntax:
[text* your-name placeholder "Your Name"]
[email* your-email placeholder "Email"]
[tel your-phone placeholder "+7 (___) ___-__-__"]
[textarea your-message placeholder "Message" 10x5]
[submit "Send"]
Asterisk after field type (text*, email*) means required. Form is inserted on page via shortcode [contact-form-7 id="123"].
Email Setup
Mail tab in form editor:
To: [email protected]
From: [your-name] <[email protected]>
Reply-To: [your-email]
Subject: Request from site: [your-name]
Body:
Name: [your-name]
Email: [your-email]
Phone: [your-phone]
Message: [your-message]
Mail (2) tab — second email, e.g., auto-reply to client.
Storing Submissions in Database
CF7 itself doesn't save submissions — only sends emails. To store submissions, install Flamingo add-on:
Plugins → Add New → Flamingo → Install
After installation, "Flamingo" menu appears with "Inbound Messages" section — all form submissions are there.
Spam Protection
Built-in protection — honeypot and Akismet integration:
// In form settings - Additional Settings tab
acceptance_as_validation: on
For reCAPTCHA v3: Contacts → Integration → reCAPTCHA — enter keys from Google. Tag [recaptcha] is added to form.
Cloudflare Turnstile connects via CF7 Turnstile plugin.
Custom Validation
add_filter( 'wpcf7_validate_tel', function( $result, $tag ) {
$value = isset( $_POST[ $tag->name ] ) ? trim( $_POST[ $tag->name ] ) : '';
if ( $tag->is_required() && ! preg_match( '/^\+7[\d\s\-\(\)]{10,}$/', $value ) ) {
$result->invalidate( $tag, 'Enter valid Russian phone number' );
}
return $result;
}, 10, 2 );
Handling Submissions
add_action( 'wpcf7_mail_sent', function( $contact_form ) {
$submission = WPCF7_Submission::get_instance();
if ( ! $submission ) return;
$data = $submission->get_posted_data();
$name = sanitize_text_field( $data['your-name'] ?? '' );
$email = sanitize_email( $data['your-email'] ?? '' );
// Send to Telegram, CRM etc.
send_telegram_notification( "New request from $name ($email)" );
} );
Dynamic Default Values
CF7 supports special tags for dynamic data substitution:
[hidden page-url "https://[_site_url][_url]"]
[hidden user-login "[_user_login]"]
[text* name default:"[_logged_in_user first_name]"]
For more flexible values — wpcf7_form_tag filter:
add_filter( 'wpcf7_form_default_value', function( $value, $tag ) {
if ( 'current-product' === $tag->name ) {
return get_the_title(); // substitute current page title
}
return $value;
}, 10, 2 );
File Attachments
[file upload-file limit:2mb filetypes:pdf|doc|docx]
Files are attached to email and deleted from server after sending. To save files — need custom code:
add_action( 'wpcf7_mail_sent', function( $form ) {
$submission = WPCF7_Submission::get_instance();
$uploaded = $submission->uploaded_files();
foreach ( $uploaded as $field => $path ) {
// copy $path to /uploads/submissions/
copy( $path, WP_CONTENT_DIR . '/uploads/submissions/' . basename( $path ) );
}
} );
CF7 Limitations
No conditional logic, no multi-step forms, no built-in submission storage, no visual editor. For simple "name + phone + message" — perfect. For complex forms, look at Gravity Forms or WPForms.
Timeline
Setting up one or two forms with email and spam protection — 2–4 hours.







