使用Netlify Forms在Next.Js中建立聯絡表單

使用Netlify Forms在Next.Js中建立聯絡表單

作為網站所有者,擁有一個易於使用並能確保訪客資訊保安的聯絡表單至關重要。設計良好的聯絡表單是與潛在客戶接觸並與受眾建立信任的絕佳方式。本指南結束時,您將擁有一個基於 Netlify 表單的全功能聯絡表單,並將其整合到您的 Next.js 應用程式中,使您能夠輕鬆接收和管理使用者諮詢。

建立一個有效、可靠的聯絡表單對於現代線上業務至關重要。為訪問者提供安全、便捷的聯絡方法至關重要,而聯絡表單正是完美的解決方案。通過使用聯絡表單,您可以簡化溝通流程,方便訪客就任何問題或疑慮與您聯絡。Nextjs 是一個流行的 React 框架,以其伺服器端渲染和無縫的開發人員體驗而聞名,我們將在本教程中探討如何將 Nextjs 與 Netlify 表單(Netlify 提供的強大表單處理服務)相結合。

設定開發環境

在開始之前,我們要使用下面的命令列設定 Next.js 環境。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npx create-next-app@latest
npx create-next-app@latest
npx create-next-app@latest

請按照下面的提示操作:

設定 Next.js 環境

之後,我們的 “下一個應用程式” 就準備就緒了,因此我們可以進入編輯器,在這裡我們要做的工作最多。我們可以檢視下面的樹形結構。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
form-app
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── src
└── app
├── favicon.ico
├── globals.css
├── layout.js
└── page.js
└── tailwind.config.js
form-app ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── src └── app ├── favicon.ico ├── globals.css ├── layout.js └── page.js └── tailwind.config.js
form-app
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── src
└── app
├── favicon.ico
├── globals.css
├── layout.js
└── page.js
└── tailwind.config.js

建立聯絡表單元件

在本文中,我們有三種方法來實現 Netlify 表單與 Next.js 的整合;首先,我們要看看簡化方法,然後再看其他方法。要建立表單元件,我們先瀏覽 layout.js 檔案。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
export default function RootLayout({ children }) { return ( <html lang="en"> <body className={inter.className}>{children}</body> </html> ); }
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}

html 標籤下,我們將建立一個帶有各種標籤和屬性(如 labelinput)的 form 欄位。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//layout.js//
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
{children}
<div>
<h2>Contact us!</h2>
<form>
<div>
<label for="name">Name</label>
<input type="text" id="name" name="name" />
</div>
<div>
<label for="email">Email</label>
<input type="email" id="email" name="email" />
</div>
<div>
<label for="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
</div>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
);
}
//layout.js// export default function RootLayout({ children }) { return ( <html lang="en"> <body className={inter.className}> {children} <div> <h2>Contact us!</h2> <form> <div> <label for="name">Name</label> <input type="text" id="name" name="name" /> </div> <div> <label for="email">Email</label> <input type="email" id="email" name="email" /> </div> <div> <label for="message">Message</label> <textarea id="message" name="message" rows="4"></textarea> </div> <button type="submit">Submit</button> </form> </div> </body> </html> ); }
//layout.js//
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
{children}
<div>
<h2>Contact us!</h2>
<form>
<div>
<label for="name">Name</label>
<input type="text" id="name" name="name" />
</div>
<div>
<label for="email">Email</label>
<input type="email" id="email" name="email" />
</div>
<div>
<label for="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
</div>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
);
}

這個表單沒有太多噱頭,非常簡單。啟動應用程式(通常使用 npm run dev )後,訪問 localhost:3000 。你應該會看到一個類似下面這樣的表單,這取決於你是如何設計的:

聯絡表單

目前,如果您嘗試將其部署到 Netlify,什麼也不會發生。這是一個直接的表單,沒有任何連線來讓表單欄位做任何事情。因此,讓我們改變這一點。

為表單新增 Netlify 屬性

讓我們返回 layout.js,在 form 標籤中新增 Netlify 屬性,這有助於將表單連結到 Netlify 伺服器。說明一下,這些屬性是 netlifydata-netlify='true'netlify='true' 。要知道,它們的工作方式都是一樣的,所以無論你選擇使用哪一種,都能完美地工作。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//layout.js//
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
{children}
<div>
<h2>Contact us!</h2>
<form name="contact" method="post" netlify>
<input type="hidden" name="form-name" value="contact" />
<div>
<label for="name">Name</label>
<input type="text" id="name" name="name" />
</div>
.....
</form>
</div>
</body>
</html>
);
}
//layout.js// export default function RootLayout({ children }) { return ( <html lang="en"> <body className={inter.className}> {children} <div> <h2>Contact us!</h2> <form name="contact" method="post" netlify> <input type="hidden" name="form-name" value="contact" /> <div> <label for="name">Name</label> <input type="text" id="name" name="name" /> </div> ..... </form> </div> </body> </html> ); }
  //layout.js//
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
{children}
<div>
<h2>Contact us!</h2>
<form name="contact" method="post" netlify>
<input type="hidden" name="form-name" value="contact" />
<div>
<label for="name">Name</label>
<input type="text" id="name" name="name" />
</div>
.....
</form>
</div>
</body>
</html>
);
}

之後,我們儲存並部署到 Netlify,然後進入下一步,在 Netlify 中啟用表單。

處理表單提交

您可以使用 Netlify 的無伺服器表單管理功能管理表單,而無需呼叫額外的 API 或新增複雜的 JavaScript 程式碼。一旦開啟,內建表單識別功能可使其構建系統在部署時自動解析您的 HTML,無需使用 API 或新增狀態函式。首先,我們必須在 Netlify 網站的站點配置中 automatic form detection system

Netlify 網站的站點配置

現在我們的步驟已經完成,因此只要訪問者訪問您的網站並決定提交表單,他們就會收到下面的成功資訊,表明 Netlify 已收到他們的資訊。

成功提交表單

如果我們轉到 Netlify 和網站儀表盤,在表單提交下,我們會看到網站訪客提交的表單列表。

網站訪客提交的表單列表

公平地說,這種方法主要適用於靜態網站,例如包含 HTML 的網站(Next.js 就是其中之一)。部署網站時,處理機器人會搜尋 netlify 屬性,而它們只能理解 HTML 形式的屬性。因此,如果我們有一個想要部署到生產環境的 Next 應用程式,在 JSX 表單中新增上述屬性後,該表單將無法工作,因為它們無法檢測到使用 Javascript 呈現的表單。因此,我們可以使用另外兩種方法來讓 Netlify 理解我們的表單欄位及其 Javascript 檔案中的屬性: 無狀態和有狀態元件表單。

無狀態元件

對於我們的無狀態 React 元件,我們要做的就是新增一個帶有 hidden 屬性的靜態  html  表單欄位。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<form name="contact" netlify="true" hidden>
<input type="text" name="name" />
<input type="email" name="email" />
<textarea name="message"></textarea>
</form>;
<form name="contact" netlify="true" hidden> <input type="text" name="name" /> <input type="email" name="email" /> <textarea name="message"></textarea> </form>;
<form name="contact" netlify="true" hidden>
<input type="text" name="name" />
<input type="email" name="email" />
<textarea name="message"></textarea>
</form>;

在本例中,我們將把它新增到 layout.js 中,因為它包含一個 html 標記。由於我們將為表單新增 hidden 屬性,使使用者和螢幕閱讀器無法看到表單,因此可以移除 label 和 submit 元件。

JSX 表單中新增隱藏輸入標籤

JSX 表單中,必須另外包含一個 hidden 型別元素,其 name 和 value 屬性如下程式碼所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<input type="hidden" name="form-name" value="contact" />
<input type="hidden" name="form-name" value="contact" />
<input type="hidden" name="form-name" value="contact" />

現在,您的 Pages.js 檔案應該如下所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export default function Home() {
return (
<div>
<h2>Contact Us</h2>
<form name="contact" method="post">
<input type="hidden" name="form-name" value="contact" />
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" />
</div>
<div>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" />
</div>
<div>
<label htmlFor="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
export default function Home() { return ( <div> <h2>Contact Us</h2> <form name="contact" method="post"> <input type="hidden" name="form-name" value="contact" /> <div> <label htmlFor="name">Name</label> <input type="text" id="name" name="name" /> </div> <div> <label htmlFor="email">Email</label> <input type="email" id="email" name="email" /> </div> <div> <label htmlFor="message">Message</label> <textarea id="message" name="message" rows="4"></textarea> </div> <button type="submit">Submit</button> </form> </div> ); }
export default function Home() {
return (
<div>
<h2>Contact Us</h2>
<form name="contact" method="post">
<input type="hidden" name="form-name" value="contact" />
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" />
</div>
<div>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" />
</div>
<div>
<label htmlFor="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}

如果您在瀏覽器中執行應用程式,您應該可以看到表單;當您的應用程式部署到 Netlify 後,您就可以提交表單了。

有狀態元件

在本例中,我們將建立一個包含狀態函式的 Contact.js 檔案,然後將其匯入我們的 page.js 。至於 layout.js ,它仍然是隱藏的。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//Contact.js//
const encode = (data) => {
return Object.keys(data)
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
.join("&");
};
const Contact = () => {
const [formData, setFormData] = useState({
name: "",
email: "",
message: "",
});
const handleSubmit = (e) => {
e.preventDefault();
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({ "form-name": "contact", ...formData }),
})
.then(() => alert("Success!"))
.catch((error) => alert(error));
};
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prevData) => ({
...prevData,
[name]: value,
}));
};
return (
<div>
<h2>Contact Us</h2>
<form onSubmit={handleSubmit}>...</form>
</div>
);
};
export default Contact;
//Contact.js// const encode = (data) => { return Object.keys(data) .map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key])) .join("&"); }; const Contact = () => { const [formData, setFormData] = useState({ name: "", email: "", message: "", }); const handleSubmit = (e) => { e.preventDefault(); fetch("/", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: encode({ "form-name": "contact", ...formData }), }) .then(() => alert("Success!")) .catch((error) => alert(error)); }; const handleChange = (e) => { const { name, value } = e.target; setFormData((prevData) => ({ ...prevData, [name]: value, })); }; return ( <div> <h2>Contact Us</h2> <form onSubmit={handleSubmit}>...</form> </div> ); }; export default Contact;
//Contact.js//
const encode = (data) => {
return Object.keys(data)
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
.join("&");
};
const Contact = () => {
const [formData, setFormData] = useState({
name: "",
email: "",
message: "",
});
const handleSubmit = (e) => {
e.preventDefault();
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({ "form-name": "contact", ...formData }),
})
.then(() => alert("Success!"))
.catch((error) => alert(error));
};
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prevData) => ({
...prevData,
[name]: value,
}));
};
return (
<div>
<h2>Contact Us</h2>
<form onSubmit={handleSubmit}>...</form>
</div>
);
};
export default Contact;

encode 函式將表單資料轉換為 URL 編碼字串。它將一個物件(data)作為輸入,遍歷其鍵,並對鍵及其對應的值進行編碼。然後用”&”將編碼後的鍵值對連線起來,形成一個 URL 編碼字串。主要功能元件 “Contact” 使用 useState React 鉤子來初始化和管理表單資料狀態。formData 狀態儲存了 nameemail, 和  message 輸入的值。任何輸入欄位發生變化時,都會呼叫 handleChange 函式。它會根據之前的狀態建立一個新物件,並用新值更新特定欄位(姓名、電子郵件或訊息),從而更新表單資料狀態。

新增成功訊息

與 Netlify 重定向頁面的靜態和無狀態方法相反,對於有狀態元件,為避免重定向錯誤(即 404 訊息),我們建立了 handleSubmit 函式,該函式在表單填寫並提交後啟動。該函式會阻止預設的表單提交行為,並使用 Fetch API 向伺服器傳送 POST 請求。它將表單資料編碼為 URL 引數傳送,並將 form-name 引數設定為  'contact'。如果請求成功,則會顯示 “Success!” 提示;否則會顯示錯誤提示。

表單錯誤資訊

小結

掌握建立動態聯絡表單的技巧可以大大提高您的網路開發技能。Next.js 和 Netlify Forms 的無縫整合不僅簡化了流程,還使您能夠輕鬆建立互動式、使用者友好的聯絡表單。通過利用伺服器端渲染、無狀態和有狀態元件的強大功能以及 Netlify 表單的簡易性,您可以為網站訪問者提供一個流暢且引人入勝的交流渠道。因此,請深入瞭解 Next.js 和 Netlify 表單,開啟一個充滿可能性的領域,打造現代、有效的網路解決方案,給人留下深刻印象。

相關資源:

評論留言