updated form
This commit is contained in:
70
NETLIFY-FORMS-SETUP.md
Normal file
70
NETLIFY-FORMS-SETUP.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Netlify Forms Setup Guide
|
||||
|
||||
This document explains how the contact form has been configured to work with Netlify's built-in form handling service.
|
||||
|
||||
## Changes Made
|
||||
|
||||
1. **Form Component Modifications**
|
||||
- Added `data-netlify="true"` attribute to enable Netlify Forms
|
||||
- Added `name="contact"` attribute to identify the form
|
||||
- Added a honeypot field with `data-netlify-honeypot="bot-field"` to prevent spam
|
||||
- Added a hidden input with the form name for Netlify to process the form correctly
|
||||
|
||||
2. **Form Handling Script Updates**
|
||||
- Removed CSRF token generation and validation (not needed with Netlify Forms)
|
||||
- Updated form submission to use Netlify's form handling endpoint
|
||||
- Simplified error handling and success messaging
|
||||
|
||||
3. **Netlify Configuration**
|
||||
- Updated `netlify.toml` to explicitly enable form processing
|
||||
|
||||
## Configuring Form Notifications in Netlify
|
||||
|
||||
After deploying your site, follow these steps to set up email notifications for form submissions:
|
||||
|
||||
1. **Access Form Settings**
|
||||
- Log in to your Netlify dashboard
|
||||
- Select your site
|
||||
- Go to **Site settings** > **Forms**
|
||||
|
||||
2. **Verify Form Detection**
|
||||
- You should see your "contact" form listed
|
||||
- If not, check your deployment logs for any issues
|
||||
|
||||
3. **Set Up Form Notifications**
|
||||
- Click on your form name
|
||||
- Go to the **Outgoing notifications** tab
|
||||
- Click **Add notification** and select **Email notification**
|
||||
- Configure the email address where you want to receive form submissions
|
||||
- Customize the subject line and other settings as needed
|
||||
|
||||
4. **Test the Form**
|
||||
- Visit your live site
|
||||
- Submit a test message through the contact form
|
||||
- Verify you receive the notification email
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If your form isn't working properly:
|
||||
|
||||
1. **Check Form Detection**
|
||||
- Ensure your form was detected during deployment
|
||||
- Look for "Processing forms from HTML" in your deploy logs
|
||||
|
||||
2. **Verify Form Markup**
|
||||
- Ensure the form has `data-netlify="true"`
|
||||
- Confirm the hidden input field has `name="form-name"` with the correct form name
|
||||
|
||||
3. **Check for JavaScript Errors**
|
||||
- Open your browser's developer console
|
||||
- Look for any errors during form submission
|
||||
|
||||
4. **Review Spam Filtering**
|
||||
- Check if submissions are being marked as spam
|
||||
- Adjust spam filtering settings in Netlify if needed
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Netlify Forms Documentation](https://docs.netlify.com/forms/setup/)
|
||||
- [Form Notifications](https://docs.netlify.com/forms/notifications/)
|
||||
- [Spam Filtering](https://docs.netlify.com/forms/spam-filters/)
|
10
netlify.toml
10
netlify.toml
@@ -1,9 +1,19 @@
|
||||
[build]
|
||||
publish = "dist"
|
||||
command = "npm run build"
|
||||
|
||||
[build.processing.html]
|
||||
pretty_urls = false
|
||||
|
||||
[[headers]]
|
||||
for = "/_astro/*"
|
||||
[headers.values]
|
||||
Cache-Control = "public, max-age=31536000, immutable"
|
||||
|
||||
# Netlify Form handling
|
||||
[build.processing]
|
||||
skip_processing = false
|
||||
|
||||
[build.processing.forms]
|
||||
# Enable Netlify Forms processing
|
||||
enabled = true
|
||||
|
@@ -463,39 +463,12 @@ import { UI } from 'astrowind:config';
|
||||
setupContactForm();
|
||||
});
|
||||
|
||||
// Fetch CSRF token from the server
|
||||
async function fetchCsrfToken() {
|
||||
console.log('Fetching CSRF token');
|
||||
try {
|
||||
const response = await fetch('/api/contact?csrf=true');
|
||||
console.log('CSRF response status:', response.status);
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('CSRF request failed:', response.statusText);
|
||||
return '';
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('CSRF token received:', data.csrfToken ? 'yes' : 'no');
|
||||
return data.csrfToken;
|
||||
} catch (error) {
|
||||
console.error('Error fetching CSRF token:', error);
|
||||
console.error('Error details:', error.message);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
// Netlify form handling setup
|
||||
|
||||
async function setupContactForm() {
|
||||
const contactForm = document.getElementById('contact-form');
|
||||
if (!contactForm) return;
|
||||
|
||||
// Get CSRF token and set it in the form
|
||||
const csrfTokenInput = contactForm.querySelector('#csrf_token');
|
||||
if (csrfTokenInput) {
|
||||
const token = await fetchCsrfToken();
|
||||
csrfTokenInput.value = token;
|
||||
}
|
||||
|
||||
// Form validation and submission
|
||||
contactForm.addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
@@ -530,81 +503,24 @@ import { UI } from 'astrowind:config';
|
||||
// Add timestamp to help prevent duplicate submissions
|
||||
formData.append('timestamp', Date.now().toString());
|
||||
|
||||
console.log('Sending form data to /api/contact');
|
||||
const response = await fetch('/api/contact', {
|
||||
// Submit the form to Netlify
|
||||
console.log('Submitting form to Netlify');
|
||||
const response = await fetch('/', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: new URLSearchParams(formData).toString()
|
||||
});
|
||||
|
||||
console.log('Response status:', response.status);
|
||||
const result = await response.json();
|
||||
console.log('Response data:', result);
|
||||
|
||||
if (result.success) {
|
||||
if (response.ok) {
|
||||
console.log('Form submission successful');
|
||||
// Show success message
|
||||
document.getElementById('form-success').classList.remove('hidden');
|
||||
contactForm.reset();
|
||||
|
||||
// Get a new CSRF token for next submission
|
||||
console.log('Getting new CSRF token');
|
||||
const newToken = await fetchCsrfToken();
|
||||
console.log('New CSRF token:', newToken ? 'received' : 'not received');
|
||||
if (csrfTokenInput) {
|
||||
csrfTokenInput.value = newToken;
|
||||
}
|
||||
} else {
|
||||
console.log('Form submission failed:', result);
|
||||
// Show specific error messages instead of generic form error
|
||||
if (result.errors) {
|
||||
console.log('Form errors:', result.errors);
|
||||
|
||||
// Only show the generic error if there are no field-specific errors
|
||||
// or if there's a server error not related to a specific field
|
||||
const hasFieldErrors = Object.keys(result.errors).some(field =>
|
||||
['name', 'email', 'message', 'disclaimer', 'csrf'].includes(field)
|
||||
);
|
||||
|
||||
if (!hasFieldErrors) {
|
||||
document.getElementById('form-error').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Display field-specific errors
|
||||
Object.keys(result.errors).forEach(field => {
|
||||
const inputElement = contactForm.querySelector(`[name="${field}"]`);
|
||||
if (inputElement) {
|
||||
const feedbackElement = inputElement.closest('div').querySelector('.invalid-feedback');
|
||||
if (feedbackElement) {
|
||||
feedbackElement.textContent = result.errors[field];
|
||||
feedbackElement.classList.remove('hidden');
|
||||
inputElement.classList.add('border-red-500');
|
||||
|
||||
// Special handling for checkbox
|
||||
if (field === 'disclaimer') {
|
||||
const checkboxContainer = inputElement.closest('.flex.items-start');
|
||||
if (checkboxContainer) {
|
||||
checkboxContainer.classList.add('checkbox-error');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// If no specific errors, show the generic error
|
||||
document.getElementById('form-error').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// If CSRF token is invalid, get a new one
|
||||
if (result.errors && result.errors.csrf) {
|
||||
console.log('CSRF token invalid, getting new token');
|
||||
const newToken = await fetchCsrfToken();
|
||||
if (csrfTokenInput) {
|
||||
csrfTokenInput.value = newToken;
|
||||
}
|
||||
}
|
||||
console.log('Form submission failed');
|
||||
document.getElementById('form-error').classList.remove('hidden');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error submitting form:', error);
|
||||
|
@@ -15,7 +15,7 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
|
||||
}
|
||||
</style>
|
||||
|
||||
<form id="contact-form" action="/api/contact" method="POST" class="needs-validation" novalidate>
|
||||
<form id="contact-form" name="contact" method="POST" class="needs-validation" data-netlify="true" data-netlify-honeypot="bot-field" novalidate>
|
||||
|
||||
<!-- Form status messages -->
|
||||
<div id="form-success" class="hidden mb-6 p-4 bg-green-100 border border-green-200 text-green-700 rounded-lg">
|
||||
@@ -26,8 +26,13 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
|
||||
There was an error sending your message. Please check all fields and try again.
|
||||
</div>
|
||||
|
||||
<!-- CSRF Token - Will be populated via JavaScript -->
|
||||
<input type="hidden" name="csrf_token" id="csrf_token" value="" />
|
||||
<!-- Netlify form name -->
|
||||
<input type="hidden" name="form-name" value="contact" />
|
||||
|
||||
<!-- Honeypot field to prevent spam -->
|
||||
<p class="hidden">
|
||||
<label>Don't fill this out if you're human: <input name="bot-field" /></label>
|
||||
</p>
|
||||
{
|
||||
inputs &&
|
||||
inputs.map(
|
||||
|
Reference in New Issue
Block a user