Gridsome - SpamBlock Pixel and Forms Integration

Learn how to integrate SpamBlock Pixel and Forms solution with Gridsome static sites. Complete example with main.js configuration and Vue component form handling.

Overview

This example shows how to integrate both the SpamBlock Pixel and SpamBlock Forms solution with Gridsome, a Vue.js-powered 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 main.js

Add the SpamBlock Pixel script in src/main.js:

import DefaultLayout from "~/layouts/Default.vue";

export default function(Vue, { router, head, isClient }) {
  // Add SpamBlock Pixel script
  head.script.push({
    src: "https://pixel.spamblock.io/latest.js",
    defer: true,
  });

  // Set default layout as a global component
  Vue.component("Layout", DefaultLayout);
}

Step 2: Create Contact Form Component

Create a contact form component:

<template>
  <form ref="formRef">
    <label for="name">Name</label>
    <input id="name" v-model="formData.name" name="name" type="text" required />

    <label for="email">Email Address</label>
    <input
      id="email"
      v-model="formData.email"
      name="email"
      type="email"
      required
    />

    <label for="message">Message</label>
    <textarea
      id="message"
      v-model="formData.message"
      name="message"
      required
    ></textarea>

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

    <p v-if="message">{{ message }}</p>
  </form>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        name: "",
        email: "",
        message: "",
      },
      isSubmitting: false,
      message: "",
    };
  },
  mounted() {
    const form = this.$refs.formRef;
    if (!form) return;

    const handleAllowed = async (event) => {
      event.preventDefault();
      this.isSubmitting = true;
      this.message = "";

      const formDataObj = new FormData(event.target);

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

        if (response.ok) {
          this.message = "Submission successful!";
          form.reset();
          this.formData = { name: "", email: "", message: "" };
        } else {
          this.message = "There was an error submitting the form.";
        }
      } catch (error) {
        this.message = "Network error. Please try again.";
        console.error("Error:", error);
      } finally {
        this.isSubmitting = false;
      }
    };

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

    this.$once("hook:beforeDestroy", () => {
      form.removeEventListener("spamblock:allowed", handleAllowed);
    });
  },
};
</script>

What This Example Shows

  • How to add SpamBlock Pixel to Gridsome sites via main.js
  • Vue.js component form handling in Gridsome
  • Options API pattern for Vue components
  • Proper cleanup of event listeners

When to Use It

Use this approach when:

  • You're building a Gridsome static site
  • You want to protect forms on a statically generated site
  • You're using Vue.js components
  • You prefer Vue Options API

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. Gridsome component handles the allowed submission

Common Mistakes

  1. Wrong file for script injection - Use main.js to add scripts via head.script.push()
  2. Not using head API - Use Gridsome's head API for proper script injection
  3. Missing ref - Use $refs to access the form DOM element
  4. Not cleaning up - Use $once('hook:beforeDestroy') to clean up event listeners
  5. Build-time vs runtime - Remember Gridsome builds static HTML, pixel runs at runtime
  6. Vue lifecycle - Use mounted hook to ensure DOM is ready

Learn More