ID formulir

Nuxt

Komponen Nuxt yang mengirim sebagai formulir biasa sebelum hidrasi dan dengan $fetch setelahnya, dengan ID formulir di runtime config. Berfungsi dengan nuxt generate.

Nuxt merender formulir di server, jadi HTML yang sampai ke browser sudah berupa formulir yang berfungsi. Sampai aplikasi terhidrasi, formulir mengirim seperti formulir HTML biasa; setelah itu, komponen mengambil alih dan menampilkan hasilnya di tempat. Tidak ada yang berjalan di server Anda, jadi ini juga berfungsi sebagai situs statis yang dibangun dengan nuxt generate.

Untuk mengirim dari server route Nuxt dengan secret key, lihat Vue.

Penyiapan

  1. Taruh ID formulir di runtime config

    nuxt.config.ts
    export default defineNuxtConfig({
      runtimeConfig: {
        public: {
          ikiformFormId: "frm_xxxxxxxxxxxxxxxx",
        },
      },
    });

    Timpa per environment dengan NUXT_PUBLIC_IKIFORM_FORM_ID. Dengan nuxt generate, nilainya ditanam saat build, jadi atur variabelnya di environment build.

  2. Tambahkan komponen

    app/components/ContactForm.vue
    <script setup lang="ts">
    type Result =
      | { ok: true; id: string }
      | { ok: false; error: { message: string; fields?: Record<string, string[]> } };
    
    const config = useRuntimeConfig();
    const endpoint = `https://ikiform.com/f/${config.public.ikiformFormId}`;
    
    const status = ref<"idle" | "sending" | "sent" | "error">("idle");
    const errors = ref<Record<string, string[]>>({});
    const message = ref("");
    
    async function onSubmit(event: Event) {
      status.value = "sending";
      const result = await $fetch<Result>(endpoint, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new FormData(event.currentTarget as HTMLFormElement),
        ignoreResponseError: true,
      }).catch(() => null);
      if (result?.ok) {
        status.value = "sent";
        return;
      }
      errors.value = result?.error.fields ?? {};
      message.value = result?.error.message ?? "Couldn't reach the server. Try again.";
      status.value = "error";
    }
    </script>
    
    <template>
      <p v-if="status === 'sent'">Thanks, we got it.</p>
      <form v-else :action="endpoint" method="post" @submit.prevent="onSubmit">
        <label>
          Email
          <input name="email" type="email" autocomplete="email" required />
        </label>
        <p v-if="errors.email">{{ errors.email[0] }}</p>
        <label>
          Message
          <textarea name="message" rows="5" />
        </label>
        <input type="hidden" name="_redirect" value="https://example.com/thanks" />
        <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
        <p v-if="status === 'error' && !errors.email" role="alert">{{ message }}</p>
        <button :disabled="status === 'sending'">{{ status === "sending" ? "Sending" : "Send" }}</button>
      </form>
    </template>
    • Di Nuxt 3, taruh di components/, bukan app/components/.
    • ignoreResponseError: true mencegah $fetch melempar error pada 4xx, jadi envelope error kembali sebagai data. Hanya kegagalan jaringan yang sampai ke catch.
    • @submit.prevent baru ada setelah aplikasi terhidrasi. Sebelum itu, browser mengirim ke action dan mengikuti _redirect.
  3. Pakai di halaman

    app/pages/contact.vue
    <template>
      <ContactForm />
    </template>

Fallback-nya butuh server rendering atau prerendering. Dengan ssr: false, halaman kosong sampai JavaScript berjalan, jadi tidak ada formulir yang bisa dikirim tanpanya.

Domain yang diizinkan

Cantumkan domain produksi plus host pratinjau dari tempat Anda deploy.

Tempat formulir berjalanTambahkan ke Domain yang diizinkan
nuxt devlocalhost. Ini cocok dengan http://localhost:3000: Ikiform hanya membandingkan nama host, tidak pernah port.
Domain Andaexample.com, yang juga mencakup www.example.com
Vercelyour-project.vercel.app. URL pratinjau seperti your-project-git-branch-team.vercel.app tidak cocok dengannya; tambahkan host pratinjau persisnya selama Anda menguji.
Netlifyyour-site.netlify.app. Deploy preview (deploy-preview-12--your-site.netlify.app) dan branch deploy (branch--your-site.netlify.app) bukan subdomainnya, jadi tambahkan host pratinjau persisnya selama Anda menguji.
Cloudflare Pagesyour-project.pages.dev. URL pratinjau seperti abc123.your-project.pages.dev adalah subdomainnya, jadi sudah cocok.
  • Jangan pernah menambahkan vercel.app, netlify.app, atau pages.dev saja. Setiap situs di host itu akan cocok, termasuk milik orang lain.

Daftar periksa pengujian

  1. Jalankan nuxt dev dengan localhost di domain yang diizinkan, lalu kirim. Pesan terima kasih seharusnya menggantikan formulir.
  2. Matikan JavaScript di dev tools browser, muat ulang, lalu kirim. Anda seharusnya mendarat di halaman terima kasih Ikiform secara lokal, atau /thanks di domain https: Anda.
  3. Kirim email yang tidak valid dengan field yang sudah didefinisikan dan pastikan pesannya muncul di bawah field.
  4. Jalankan nuxt generate, deploy output-nya, lalu kirim dari host pratinjau.

Pemecahan masalah

Yang Anda lihatAlasanSolusi
FetchError: [POST] "https://ikiform.com/f/...": 422ignoreResponseError tidak ada, jadi $fetch melempar errorTambahkan ignoreResponseError: true.
404 not_found, dan action berakhir di /f/undefinedID formulir tidak diatur saat situs di-buildAtur NUXT_PUBLIC_IKIFORM_FORM_ID di environment build, atau nilai default di nuxt.config.ts.
Tanpa JavaScript, tidak terjadi apa-apaHalaman dirender di client dengan ssr: falseAktifkan server rendering atau prerender halamannya.
Kiriman masuk ke filter spam dengan origin_mismatchHalaman yang mengirim tidak ada di domain yang diizinkan formulirTambahkan host dari tabel di atas. Jika Reject dipilih, kiriman yang sama mendapat 403 origin_not_allowed.