Home / Οδηγοί / Ενσωμάτωση φόρμας επικοινωνίας React (Εφαρμογές Vite & Μονοσελίδας)
ΟΔΗΓΟΣ INTEGRATION · REACT & SPA

Ενσωμάτωση φόρμας επικοινωνίας React (Εφαρμογές Vite & Μονοσελίδας)

Πώς να προσθέσετε φόρμες επικοινωνίας και σχολίων στις Εφαρμογές React Single-Page (SPA) που έχουν δημιουργηθεί με την εφαρμογή Vite ή Create React, με προστασία από ανεπιθύμητα μηνύματα honeypot και άμεσες ειδοποιήσεις εισερχομένων.

1. Τυπικό στοιχείο φόρμας επαφής React με Vite

Αυτό το ελαφρύ εξάρτημα React χρησιμοποιεί τυπικά άγκιστρα React (useState) και το API Fetch του προγράμματος περιήγησης για υποβολή απευθείας στο δημόσιο τελικό σημείο του Lugatu. Δεν απαιτούνται εξωτερικές βιβλιοθήκες φορμών ή διακομιστές υποστήριξης.

src/components/ContactForm.tsx tsx
import React, { useState } from 'react';

export function ContactForm() {
  const [formData, setFormData] = useState({ name: '', email: '', message: '', _gotcha: '' });
  const [status, setStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
  const [errorMessage, setErrorMessage] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (formData._gotcha) return; // Silent discard for automated bot traps

    setStatus('submitting');
    setErrorMessage('');

    try {
      const response = await fetch('https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
        body: JSON.stringify({
          fields: {
            name: formData.name,
            email: formData.email,
            message: formData.message,
          },
          honeypot: formData._gotcha,
        }),
      });

      if (!response.ok) {
        throw new Error('Failed to deliver message');
      }

      setStatus('success');
      setFormData({ name: '', email: '', message: '', _gotcha: '' });
    } catch (err: any) {
      setStatus('error');
      setErrorMessage(err.message || 'Submission error. Please try again.');
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4 max-w-md">
      <div>
        <label htmlFor="react-name" className="block text-sm font-semibold mb-1">Your Name</label>
        <input
          id="react-name"
          type="text"
          required
          value={formData.name}
          onChange={(e) => setFormData({ ...formData, name: e.target.value })}
          className="w-full border rounded-xl p-2.5"
        />
      </div>

      <div>
        <label htmlFor="react-email" className="block text-sm font-semibold mb-1">Email Address</label>
        <input
          id="react-email"
          type="email"
          required
          value={formData.email}
          onChange={(e) => setFormData({ ...formData, email: e.target.value })}
          className="w-full border rounded-xl p-2.5"
        />
      </div>

      <div>
        <label htmlFor="react-message" className="block text-sm font-semibold mb-1">Message</label>
        <textarea
          id="react-message"
          rows={4}
          required
          value={formData.message}
          onChange={(e) => setFormData({ ...formData, message: e.target.value })}
          className="w-full border rounded-xl p-2.5"
        />
      </div>

      <!-- Honeypot spam defense -->
      <input
        type="text"
        name="_gotcha"
        value={formData._gotcha}
        onChange={(e) => setFormData({ ...formData, _gotcha: e.target.value })}
        style={{ display: 'none' }}
        tabIndex={-1}
        autoComplete="off"
      />

      <button
        type="submit"
        disabled={status === 'submitting'}
        className="btn-primary-editorial py-2.5 px-6"
      >
        {status === 'submitting' ? 'Sending...' : 'Send Message'}
      </button>

      {status === 'success' && (
        <p className="text-sm text-green-700 font-medium">Thank you! Your message was delivered.</p>
      )}
      {status === 'error' && (
        <p className="text-sm text-red-600">{errorMessage}</p>
      )}
    </form>
  );
}

2. Ενσωμάτωση με React Hook Form και Formik

Το τυπικό μοντέλο υποβολής JSON της Lugatu ενσωματώνεται αβίαστα με βιβλιοθήκες επικύρωσης φορμών όπως React Hook Form, Formik ή Zod. Περάστε τις σειριακές τιμές απευθείας στο αντικείμενο ωφέλιμου φορτίου πεδίων.

useLugatuForm.ts typescript
// React Hook Form submission handler
const onSubmit = async (data: FormValues) => {
  const res = await fetch(`https://www.lugatu.com/api/v1/public/forms/${import.meta.env.VITE_LUGATU_FORM_ID}/submissions`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ fields: data }),
  });
  return res.ok;
};

3. Environment Variables & Secret Separation στο React

Στο Vite, οι δημόσιες μεταβλητές έχουν το πρόθεμα VITE_. Χρησιμοποιήστε το VITE_LUGATU_FORM_ID για το αναγνωριστικό δημόσιας φόρμας. Ποτέ μην εκθέτετε το κλειδί API από διακομιστή σε διακομιστή (lug_live_...) μέσα στον πηγαίο κώδικα ή στα αποθετήρια από την πλευρά του πελάτη.

warning

Τα κλειδιά Live API που ξεκινούν με lug_live_ είναι αυστηρά δεσμευμένα για εκτέλεση από διακομιστή σε διακομιστή. Οποιοδήποτε αίτημα προγράμματος περιήγησης αποστέλλεται με ζωντανό κλειδί API απορρίπτεται με το HTTP 403.

Αμετάβλητη ασφάλεια & έλεγχος ταυτότητας

Αμετάβλητη ασφάλεια: Ποτέ μην βάζετε πρόθεμα ζωντανά κλειδιά API με VITE_ ή REACT_APP_. Οι πελάτες προγράμματος περιήγησης πρέπει να υποβάλλονται αποκλειστικά σε δημόσια τελικά σημεία χωρίς κλειδιά API.

Αντιμετώπιση προβλημάτων και κοινά σφάλματα κατάποσης

Οι υποβολές φορμών επιστρέφουν σφάλμα CORS στην κονσόλα του προγράμματος περιήγησης

Βεβαιωθείτε ότι υποβάλλεστε στο δημόσιο τελικό σημείο (https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions). Τα τελικά σημεία διακομιστή σε διακομιστή (POST /api/v1/forms/{id}/submissions) αποκλείουν ρητά τις προελεύσεις του προγράμματος περιήγησης.

Συχνές Ερωτήσεις

Μπορώ να χρησιμοποιήσω το React Hook Form ή το Formik με το Lugatu;

Ναί. Η Lugatu δέχεται τυπικό JSON με αντικείμενο πεδίου. Οποιαδήποτε βιβλιοθήκη φορμών React μπορεί να σειριοποιήσει τις τιμές της και να υποβάλει στο δημόσιο τελικό σημείο.

Είστε έτοιμοι να δημιουργήσετε το τελικό σημείο της φόρμας σας;

Ξεκινήστε δωρεάν σε δευτερόλεπτα. Δεν απαιτείται πιστωτική κάρτα.

Ξεκινήστε δωρεάν →