Nuxt.js - SpamBlock Pixel and Forms Integration

Learn how to integrate SpamBlock Pixel and Forms solution with Nuxt.js forms using the Fetch API. Complete Nuxt.js component example with Vue Composition API.

Overview

This example shows how to integrate both the SpamBlock Pixel and SpamBlock Forms solution in a Nuxt.js application using the Fetch API. 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.

<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 setup>
import { onMounted, onUnmounted, ref } from "vue";

const formRef = ref(null);
const isSubmitting = ref(false);
const message = ref("");
const formData = ref({
  name: "",
  email: "",
  message: "",
});

let pixelScript = null;
let allowedHandler = null;

onMounted(() => {
  // Load SpamBlock Pixel using Nuxt's useHead
  useHead({
    script: [
      {
        src: "https://pixel.spamblock.io/latest.js",
        defer: true,
      },
    ],
  });

  // Wait a bit for script to load, then set up event listener
  setTimeout(() => {
    if (formRef.value) {
      allowedHandler = async (event) => {
        event.preventDefault();
        isSubmitting.value = true;
        message.value = "";

        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) {
            message.value = "Submission successful!";
            formRef.value.reset();
            formData.value = { name: "", email: "", message: "" };
          } else {
            message.value = "There was an error submitting the form.";
          }
        } catch (error) {
          message.value = "Network error. Please try again.";
          console.error("Error:", error);
        } finally {
          isSubmitting.value = false;
        }
      };

      formRef.value.addEventListener("spamblock:allowed", allowedHandler);
    }
  }, 100);
});

onUnmounted(() => {
  if (formRef.value && allowedHandler) {
    formRef.value.removeEventListener("spamblock:allowed", allowedHandler);
  }
});
</script>

What This Example Shows

  • How to integrate SpamBlock Pixel with Nuxt.js
  • Using Nuxt's useHead composable for script loading
  • Vue 3 Composition API in Nuxt context
  • Proper lifecycle management
  • Client-side form handling

When to Use It

Use this approach when:

  • You're building a Nuxt.js application (Nuxt 3)
  • You want to leverage Nuxt's built-in composables
  • You need server-side rendering with client-side interactivity
  • You're using Vue 3 Composition 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. Nuxt.js component handles the allowed submission

Common Mistakes

  1. Not using useHead - Use Nuxt's useHead composable for script management
  2. Timing issues - Add a small delay to ensure pixel script loads before setting up listeners
  3. Not cleaning up event listeners - Always remove event listeners in onUnmounted
  4. Missing template ref - Use ref to access the form DOM element
  5. SSR considerations - Ensure pixel script only loads on client side
  6. Not preventing default - Always call event.preventDefault() in the event handler

Learn More