Home / מדריכים / שילוב טופס יצירת קשר זוויתי (עצמאי ואותות)
מדריך אינטגרציה · ANGULAR & SPA

שילוב טופס יצירת קשר זוויתי (עצמאי ואותות)

חבר יישומי Angular 17/18+ ל-Lugatu באמצעות רכיבים עצמאיים, אותות תגובתיים ו-HttpClient להעברת טופס יצירת קשר אמינה ללא תחזוקה של שרת SMTP.

1. רכיב טופס יצירת קשר עצמאי עם אותות ריאקטיביים

Modern Angular מעדיף רכיבים ואותות עצמאיים על פני NgModules כבדים. יישום זה מספק טופס יצירת קשר נגיש עם מצבי טעינה, שגיאה והצלחה תגובתיים הנשלחים ישירות ללוגאטו.

contact-form.component.ts typescript
import { Component, signal, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-contact-form',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <form (ngSubmit)="onSubmit()" class="space-y-4 max-w-md">
      <div>
        <label for="name" class="block text-sm font-semibold mb-1">Your Name</label>
        <input id="name" type="text" [(ngModel)]="name" name="name" required class="w-full border rounded-xl p-2.5" />
      </div>
      <div>
        <label for="email" class="block text-sm font-semibold mb-1">Email Address</label>
        <input id="email" type="email" [(ngModel)]="email" name="email" required class="w-full border rounded-xl p-2.5" />
      </div>
      <div>
        <label for="message" class="block text-sm font-semibold mb-1">Message</label>
        <textarea id="message" rows="4" [(ngModel)]="message" name="message" required class="w-full border rounded-xl p-2.5"></textarea>
      </div>

      <!-- Honeypot spam defense -->
      <input type="text" [(ngModel)]="gotcha" name="_gotcha" style="display:none !important" tabindex="-1" autocomplete="off" />

      <button type="submit" [disabled]="isSubmitting()" class="btn-primary-editorial py-2.5 px-6">
        {{ isSubmitting() ? 'Sending...' : 'Send Message' }}
      </button>

      <p *ngIf="isSuccess()" class="text-sm text-green-700 font-medium">Thank you! Your message has been received.</p>
      <p *ngIf="errorMessage()" class="text-sm text-red-600">{{ errorMessage() }}</p>
    </form>
  `,
})
export class ContactFormComponent {
  private http = inject(HttpClient);

  name = signal('');
  email = signal('');
  message = signal('');
  gotcha = signal('');

  isSubmitting = signal(false);
  isSuccess = signal(false);
  errorMessage = signal('');

  onSubmit() {
    if (this.gotcha()) return; // Silent discard for automated bot submissions

    this.isSubmitting.set(true);
    this.errorMessage.set('');

    const payload = {
      fields: {
        name: this.name(),
        email: this.email(),
        message: this.message(),
      },
      honeypot: this.gotcha(),
    };

    this.http.post('https://www.lugatu.com/api/v1/public/forms/YOUR_PUBLIC_FORM_ID/submissions', payload)
      .subscribe({
        next: () => {
          this.isSubmitting.set(false);
          this.isSuccess.set(true);
          this.name.set('');
          this.email.set('');
          this.message.set('');
        },
        error: () => {
          this.isSubmitting.set(false);
          this.errorMessage.set('Submission failed. Please try again.');
        },
      });
  }
}

2. SSR & Angular Universal Server-to-Server Forwarding

אם אפליקציית Angular שלך פועלת עם Angular SSR (מנוע צומת / אקספרס), אתה יכול לבצע פניות פרוקסי דרך מטפל במסלול בצד השרת כדי להגן על מפתח ה-API של Lugatu Server-to-Server שלך.

server.ts typescript
// Express / Node backend endpoint in Angular SSR
server.post('/api/contact', async (req, res) => {
  const { name, email, message, _gotcha } = req.body;
  if (_gotcha) return res.status(200).json({ ok: true });

  try {
    const response = await fetch(`https://www.lugatu.com/api/v1/forms/${process.env.LUGATU_FORM_ID}/submissions`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.LUGATU_API_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': crypto.randomUUID(),
      },
      body: JSON.stringify({ fields: { name, email, message } }),
    });

    res.status(response.status).json({ ok: response.ok });
  } catch (error) {
    res.status(500).json({ error: 'Failed to deliver message' });
  }
});

3. תצורת Bot Defense & Honeypot

Lugatu בודק את שדה _gotcha באופן אוטומטי. שמור אותו בלתי נראה למבקרים אנושיים באמצעות display:none ו-tabindex="-1". ספבוטים הממלאים כל קלט DOM מפעילים דיכוי שקט.

tip

לעולם אל תשתמש בתוויות טופס עבור כניסות של סיר דבש. השאר את ההשלמה האוטומטית כבויה והסר את השדה משמות נגישים לקורא מסך.

אבטחה ואימות בלתי משתנה

אי משתנה אבטחה: אסור לאגד מפתחות API של שרת לשרת (lug_live_...) בקבצי Angular בצד הלקוח או בקבצי environment.ts. השתמש בנקודת הקצה הציבורית להגשת לקוח ישירות או העברה דרך נקודות הקצה של השרת.

פתרון בעיות ושגיאות בליעה נפוצות

HTTP 403 FORBIDDEN_BROWSER_ORIGIN בעת הגשה מ-Angular

נקודות קצה בטופס ציבורי מאפשרות הגשת מקורות צולבים מכל דפדפן. אם אתה קורא לנקודת הקצה של השרת לשרת (POST /api/v1/forms/{id}/submissions) ישירות מ-Angular, עבור לנקודת הקצה הציבורית (POST /api/v1/public/forms/{id}/submissions) או העבר דרך קצה אחורי.

שאלות נפוצות

האם Lugatu תומך ב-Angular SSR עם הידרציה של הלקוח?

כֵּן. שליחת טפסים ציבוריים של Lugatu מתבצעת באמצעות אחזור בצד הלקוח או HttpClient לאחר אינטראקציה של המשתמש, התואם לחלוטין עם Angular SSR והידרציה של הלקוח.

מוכן ליצור את נקודת הקצה של הטופס שלך?

התחל בחינם תוך שניות. אין צורך בכרטיס אשראי.

התחל בחינם →