Gatsby.js - SpamBlock Pixel and Forms Integration

Learn how to integrate SpamBlock Pixel and Forms solution with Gatsby.js static sites. Complete example with gatsby-ssr.js configuration and form handling.

Overview

This example shows how to integrate both the SpamBlock Pixel and SpamBlock Forms solution with Gatsby.js, a React-based static site generator. The Pixel intercepts form submissions and scores them at the edge, while the Forms solution provides a hosted endpoint for receiving submissions.

Note: While the SpamBlock Pixel works with any backend endpoint, this example specifically demonstrates using both the Pixel and SpamBlock Forms together. The SpamBlock Forms endpoint (https://api.spamblock.io/f/{form_id}) provides a complete hosted form solution. Learn more about Forms or use your own backend endpoint with the Pixel.

Step 1: Add Pixel Script to gatsby-ssr.js

Create or update gatsby-ssr.js in your project root:

import React from "react";

export const onRenderBody = ({ setHeadComponents }) => {
  setHeadComponents([
    <script
      key="spamblock-pixel"
      src="https://pixel.spamblock.io/latest.js"
      defer
    />,
  ]);
};

Step 2: Create Contact Form Component

Create a contact form component:

import React, { useEffect, useRef, useState } from "react";

const ContactForm = () => {
  const formRef = useRef(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [message, setMessage] = useState("");

  useEffect(() => {
    const form = formRef.current;
    if (!form) return;

    const handleAllowed = async (event) => {
      event.preventDefault();
      setIsSubmitting(true);
      setMessage("");

      const formData = new FormData(event.target);

      try {
        const response = await fetch(
          "https://api.spamblock.io/f/{form_id}",
          {
            method: "POST",
            body: formData,
          }
        );

        if (response.ok) {
          setMessage("Submission successful!");
          form.reset();
        } else {
          setMessage("There was an error submitting the form.");
        }
      } catch (error) {
        setMessage("Network error. Please try again.");
        console.error("Error:", error);
      } finally {
        setIsSubmitting(false);
      }
    };

    form.addEventListener("spamblock:allowed", handleAllowed);

    return () => {
      form.removeEventListener("spamblock:allowed", handleAllowed);
    };
  }, []);

  return (
    <form ref={formRef}>
      <label htmlFor="name">Name</label>
      <input id="name" name="name" type="text" required />

      <label htmlFor="email">Email Address</label>
      <input id="email" name="email" type="email" required />

      <label htmlFor="message">Message</label>
      <textarea id="message" name="message" required></textarea>

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? "Sending..." : "Send"}
      </button>

      {message && <p>{message}</p>}
    </form>
  );
};

export default ContactForm;

What This Example Shows

  • How to add SpamBlock Pixel to Gatsby.js sites using gatsby-ssr.js
  • React component form handling in Gatsby
  • Proper cleanup of event listeners
  • Static site generation considerations

When to Use It

Use this approach when:

  • You're building a Gatsby.js static site
  • You want to protect forms on a statically generated site
  • You need the pixel available on all pages
  • You're using React components for forms

How it Works

  1. User submits form
  2. SpamBlock Pixel intercepts submission
  3. Submission scored at the edge
  4. If spam: submission blocked, event not fired
  5. If allowed: spamblock:allowed event fired
  6. Gatsby component handles the allowed submission

Common Mistakes

  1. Wrong file for script injection - Use gatsby-ssr.js for scripts that need to run on all pages
  2. Not using setHeadComponents - Use Gatsby's API to inject scripts properly
  3. Missing key prop - Always include a key prop when adding script elements
  4. Build-time vs runtime - Remember that Gatsby builds static HTML, pixel runs at runtime
  5. Not cleaning up event listeners - Always remove event listeners in cleanup
  6. SSR considerations - Pixel script should be added via SSR API, not in component

Learn More