Wie man ein Kontaktformular mit Next.js und Netlify erstellt

Avatar of Monica Powell
Monica Powell am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wir werden ein Kontaktformular mit Next.js und Netlify erstellen, das einen Bestätigungsbildschirm anzeigt und erweiterte Spam-Erkennung bietet.

Next.js ist ein leistungsstarkes React-Framework zur Entwicklung performanter React-Anwendungen, die skalieren. Durch die Integration einer Next.js-Website mit der Technologie von Netlify können wir schnell ein funktionierendes Kontaktformular einrichten, ohne serverseitigen Code schreiben zu müssen.

Es ist nicht nur ein relativ schneller Prozess, Formulare für die Verarbeitung durch Netlify einzurichten, sondern es ist auch kostenlos, um damit zu beginnen (mit bis zu 100 kostenlosen Einreichungen pro Website, die auf Netlify gehostet werden). Formulareinreichungen durchlaufen automatisch den integrierten Spamfilter von Netlify, der Akismet verwendet, und es gibt auch Optionen, die konfiguriert werden können, um die Spam-Erkennung zu erhöhen.

Erstellung des Kontaktformulars

Innerhalb der Next.js-Anwendung sollten wir eine ContactForm-Komponente erstellen, um das Kontaktformular auf der Kontaktseite darzustellen. Wenn dieses Formular unter /contact angezeigt werden soll, dann sollte die unten stehende ContactForm-Komponente mit Labels und Eingabefeldern in der Datei pages/contact.js verwendet werden.

const ContactForm = (
  <form
    name="contact-form"
    method="POST"
    action="contact/?success=true"
  >
    <label htmlFor="name">Name *</label>
    <input
      id="name"
      name="name"
      required
      type="text"
    />
    <label htmlFor="company">Company *</label>
    <input id="company" name="company" required type="text" />
    <label htmlFor="email">E-mail Address *</label>
    <input id="email" type="email" name="email" required />
    <label htmlFor="message">Message *</label>
    <textarea id="message" name="message" required></textarea>
    <button type="submit">Submit</button>
  </form>
);

Das obige Markup ist erforderlich, um ein Formular mit Feldern für Name, Firma, E-Mail-Adresse und Nachricht sowie einem Absende-Button darzustellen. Beim Absenden des Formulars sollte es basierend auf dem Wert der `action`-Attribute des Formulars von /contact zu contact/?success=true weiterleiten. Im Moment gibt es noch keinen Unterschied im Erscheinungsbild der Seite mit und ohne den Erfolgs-Query-Parameter, aber das werden wir später aktualisieren.

Unsere Datei Contact.js sieht bisher so aus

import React from "react";
const ContactPage = () => {
 const ContactForm = (/* code in above code sample*/)
 
 return (
   <div>
     <h1>Contact Us</h1>
     {ContactForm}
   </div>
 );
};
 
export default ContactPage;

Nachdem wir das grundlegende Formular eingerichtet haben, geschieht die eigentliche Magie, wenn wir zusätzliche Informationen hinzufügen, damit Netlify das Formular bei zukünftigen Website-Deployments automatisch erkennt. Um dies zu erreichen, sollten wir das Formular mit dem Attribut data-netlify="true" und einem versteckten Eingabefeld aktualisieren, das den Namen unseres Kontaktformulars enthält. In Netlify können wir nach der Navigation zu unserer Website im Dashboard und dem Klicken auf den Tab "Forms" unsere Formulareinreichungen basierend auf dem Namen anzeigen, den wir in unser verstecktes Feld eingegeben haben. Es ist wichtig, dass Formulare innerhalb einer Website eindeutige Namen haben, damit sie in Netlify ordnungsgemäß erfasst werden.

<form
  method="POST"
  name="contact-form"
  action="contact/?success=true"
  data-netlify="true"
>
<input type="hidden" name="form-name" value="contact-form" />

Nach erfolgreicher Bereitstellung der Website auf Netlify mit dem data-netlify-Attribut und dem form-name-Feld können wir die bereitgestellte Version der Website aufrufen und das Formular ausfüllen. Nach dem Absenden des Formulars und der Navigation zu https://app.netlify.com/sites/site-name/forms (wobei site-name der Name Ihrer Website ist) sollte unsere neueste Formulareinreichung erscheinen, wenn wir das Formular erfolgreich eingerichtet haben. 

Weiterleitung zur Bestätigungsseite

Um die Benutzererfahrung zu verbessern, sollten wir eine Logik hinzufügen, um bei Formularübermittlung zu einer Bestätigungsseite weiterzuleiten, wenn sich die URL zu /contact/?success=true ändert. Es besteht auch die Möglichkeit, bei der Formularübermittlung zu einer völlig anderen Seite weiterzuleiten, aber mit Query-Parametern können wir mit dem Next Router etwas Ähnliches erreichen. Dies können wir erreichen, indem wir eine neue Variable erstellen, die bestimmt, ob die Bestätigungsseite oder das Formular basierend auf dem Query-Parameter sichtbar sein soll. Der `next/router`, der mit import { useRouter } from "next/router"; importiert wird, kann verwendet werden, um die aktuellen Query-Parameter abzurufen. 

const router = useRouter();  
const confirmationScreenVisible = router.query?.success && router.query.success === "true";

In unserem Fall können die Bestätigungsseite und das Formular nie gleichzeitig sichtbar sein; daher kann die folgende Anweisung verwendet werden, um zu bestimmen, ob das Formular sichtbar ist oder nicht.

const formVisible = !confirmationScreenVisible; 

Um Benutzern die Möglichkeit zu geben, das Formular erneut einzureichen, können wir der Bestätigungsseite einen Button hinzufügen, um das Formular zurückzusetzen, indem wir die Query-Parameter löschen. Die Verwendung von router.replace (anstelle von router.push) aktualisiert nicht nur die Seite, sondern ersetzt die aktuelle Seite im Verlauf durch die Version ohne Query-Parameter. 

<button onClick={() => router.replace("/contact", undefined, { shallow: true })}> Submit Another Response </button>

Wir können dann das Formular bedingt rendern, je nachdem, ob das Formular sichtbar ist oder nicht mit

{formVisible ? ContactForm : ConfirmationMessage}

Wenn wir alles zusammenfügen, können wir den folgenden Code verwenden, um das Formular bedingt basierend auf den Query-Parametern zu rendern (die bei der Formularübermittlung aktualisiert werden)

import React, { useState } from "react";
import { useRouter } from "next/router";
 
const ContactPage = () => {
 const [submitterName, setSubmitterName] = useState("");
 const router = useRouter();
 const confirmationScreenVisible =
   router.query?.success && router.query.success === "true";
 const formVisible = !confirmationScreenVisible;
 
 const ConfirmationMessage = (
   <React.Fragment>
     <p>
       Thank you for submitting this form. Someone should get back to you within 24-48 hours.
     </p>
 
     <button onClick={() => router.replace("/contact", undefined, { shallow: true })}> Submit Another Response </button>
   </React.Fragment>
 );
 
 const ContactForm = (/* code in first code example */);
 
 return (
   <div>
     <h1>Contact Us</h1>
{formVisible ? ContactForm : ConfirmationMessage}
   </div>
 );
};
 
export default ContactPage;

Hinzufügen eines versteckten Bot-Feldes

Da die Kernfunktionalität unseres Formulars nun funktioniert, können wir zusätzliche Spam-Erkennung zu unserem Formular hinzufügen, zusätzlich zur grundlegenden Spam-Erkennung, da Akismet standardmäßig in allen Netlify-Formularen enthalten ist. Wir können dies aktivieren, indem wir data-netlify-honeypot="bot-field" zu unserem Formular hinzufügen.

<form
  className="container"
  method="POST"
  name="contact-form"
  action="contact/?success=true"
  data-netlify="true"
  data-netlify-honeypot="bot-field"
>

Wir müssen auch einen neuen versteckten Absatz erstellen, der ein Label mit dem Namen bot-field enthält, das die Eingabe enthält. Dieses Feld ist für Bots "sichtbar", aber nicht für Menschen. Wenn dieses Honeypot-Formularfeld ausgefüllt wird, erkennt Netlify einen Bot und die Einreichung wird als Spam markiert.

<p hidden>
  <label>
    Don’t fill this out: <input name="bot-field" />
  </label>
</p>

Weitere Anpassungen

  • Wir könnten eine weitere von Netlify unterstützte Spam-Schutzoption untersuchen, indem wir reCAPTCHA 2 zu einem Netlify-Formular hinzufügen.
  • Wir könnten das Formular aktualisieren, um hochladbare Dateien mit der Eingabe <input type="file"> zuzulassen.
  • Wir könnten Benachrichtigungen für Formularübermittlungen einrichten. Das geschieht unter https://app.netlify.com/sites/[your-site-name]/settings/forms , wo wir ein benutzerdefiniertes Betreff-Feld (das versteckt sein kann) für E-Mail-Benachrichtigungen einfügen können.

Vollständiger Code

Der Code für den vollständigen Website-Code ist auf GitHub verfügbar.

Bonus

Der folgende Code enthält alles, was wir besprochen haben, sowie die Logik zur Festlegung einer benutzerdefinierten Betreffzeile mit dem, was im Namensfeld eingegeben wurde.

import React, { useState } from "react";
import { useRouter } from "next/router";
 
const ContactPage = () => {
 const [submitterName, setSubmitterName] = useState("");
 const router = useRouter();
 const confirmationScreenVisible =
   router.query?.success && router.query.success === "true";
 const formVisible = !confirmationScreenVisible;
 
 const ConfirmationMessage = (
   <React.Fragment>
     <p>
       Thank you for submitting this form. Someone should get back to you
       within 24-48 hours.
     </p>
 
     <button onClick={() => router.replace("/contact", undefined, { shallow: true })}> Submit Another Response </button>
   </React.Fragment>
 );
 
 const ContactForm = (
   <form
     className="container"
     method="POST"
     name="contact-form"
     action="contact/?success=true"
     data-netlify="true"
     data-netlify-honeypot="bot-field"
   >
     <input
       type="hidden"
       name="subject"
       value={`You've got mail from ${submitterName}`}
     />
     <input type="hidden" name="form-name" value="contact-form" />
     <p hidden>
       <label>
         Don’t fill this out: <input name="bot-field" />
       </label>
     </p>
 
     <label htmlFor="name">Name *</label>
     <input
       id="name"
       name="name"
       required
       onChange={(e) => setSubmitterName(e.target.value)}
       type="text"
     />
     <label htmlFor="company">Company *</label>
     <input id="company" name="company" required type="text" />
     <label htmlFor="email">E-mail Address *</label>
     <input id="email" type="email" name="email" required />
     <label htmlFor="message">Message *</label>
     <textarea id="message" name="message" required/>
     <button type="submit">Submit</button>
   </form>
 );
 
 return (
   <div>
     <h1>Contact Us</h1>
{formVisible ? ContactForm : ConfirmationMessage}
   </div>
 );
};
 
export default ContactPage;