Skip to content

Instantly share code, notes, and snippets.

@wilgert
Last active March 26, 2022 18:51
Show Gist options
  • Save wilgert/64d44d9e4d8e94db54a56209a5b8937f to your computer and use it in GitHub Desktop.
Save wilgert/64d44d9e4d8e94db54a56209a5b8937f to your computer and use it in GitHub Desktop.
Public guestbook using Netlify Functions
  1. Add Form to HTML
  <form netlify name="guestbook" method="POST">
      <label>
        Jouw naam:
        <input name="name" type="text" required="required" minlength="2" />
      </label>

      <label>
        Bericht:
        <textarea name="message" required="required" minlength="5"></textarea>
      </label>
      <button>Verzenden</button>
    </form>
  1. Add guestbook output div to html
<div id="guestbookOutput"></div>
  1. Add luxon and custom guestbook.js script tags to html
 <script
      src="https://cdn.jsdelivr.net/npm/[email protected]/build/global/luxon.min.js"
      integrity="sha256-e2xkOE+oa0Ux7mVa39RFbhewJ4rMMlud92zYs61NHFY="
      crossorigin="anonymous"
    ></script>
    <script src="guestbook.js"></script>
  1. store guestbook.js next to html file
  2. store submissions.js in a folder called netlify/functions/ in the root of your project
  3. store package.json in root of your project
  4. create a personal access token on Netlify N.B. this access token gives full control on the Netlify api, handle with care.
  5. store this personal access token in an environment variable on Netlify (Site Settings -> Build & deploy -> Environment) called NETLIFY_PAT
  6. publish your netlify site
  7. do a single form submission to find out the form id (it's in the url when viewing the form on Netlify)
  8. add an environment variable called FORM_ID and give it the value of the formId from the previous step
  9. trigger a new deploy of your Netlify site
  10. style the form and messages using css
const DateTime = luxon.DateTime;
const handleSubmit = (e) => {
e.preventDefault();
let myForm = document.querySelector('form[name="guestbook"]');
let formData = new FormData(myForm);
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams(formData).toString(),
}).then(renderSubmissions);
};
document
.querySelector('form[name="guestbook"]')
.addEventListener("submit", handleSubmit);
const getSubmissions = () => {
return fetch("/.netlify/functions/submissions", {method: "GET"})
.then((response) => response.json());
};
function createTitle(submission) {
const dt = DateTime.fromISO(submission.created_at).setLocale('nl');
const h3El = document.createElement('h3');
h3El.classList.add('guestbook-header');
h3El.title = submission.created_at;
h3El.innerText =
`${submission.name} schreef op ${dt.toLocaleString(DateTime.DATE_HUGE)} het volgende `;
return h3El;
}
function createMessage(submission) {
const pEl = document.createElement('p');
pEl.classList.add('guestbook-messsage')
pEl.innerText = submission.message;
return pEl;
}
function createSubmission(submission) {
const el = document.createElement("div");
el.id = "guestbookSubmission_" + submission.id;
const titleEl = createTitle(submission);
const messageEl = createMessage(submission);
el.appendChild(titleEl);
el.appendChild(messageEl);
return el;
}
const renderSubmissions = () => {
const output = document.querySelector("#guestbookOutput");
output.innerHTML = "";
getSubmissions(output).then((submissions) => {
submissions.forEach((submission) => {
output.appendChild(createSubmission(submission));
});
});
};
renderSubmissions();
{
"dependencies": {
"node-fetch": "2.6.7"
}
}
// MAKE SURE YOU STORE THIS UNDER /netlify/functions
const fetch = require("node-fetch");
exports.handler = async function (event, context) {
const { NETLIFY_PAT, FORM_ID } = process.env;
const baseURL = "https://api.netlify.com/api/v1/";
const formSubmissionsPath = `forms/${FORM_ID}/submissions`;
const result = await fetch(baseURL + formSubmissionsPath, {
headers: {
Authorization: `Bearer ${NETLIFY_PAT}`,
},
})
.then((response) => response.json())
.then((submissions) =>
submissions.map(({ id, number, data: { name, message}, created_at }) => ({
id,
number,
name,
message,
created_at,
}))
);
return {
statusCode: 200,
body: JSON.stringify(result),
};
};
// exports.handler().then(console.log)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment