How to integrate Netlify Forms in an Angular app
I will walk you through how to create a form in Angular, and how to connect it to Netlify's Form functionality. We’ll create a contact form in our Angular component and a hidden form in index.html for Netlify's bot to reckognize it. It's also important to add a hidden input field in both forms to help Netlify identify the form submission.
Updated: Jul 26, 2023
Published: Jul 23, 2023
Netlify has a feature where you can send form submissions directly to them through your web application. Setting it up is explained in detail on their official web site, and I recommend reading it for more details. In this blog post, we'll go through the specifics of setting it up in Angular 16 (the principles are the same for any version of Angular 2 and above.)
First, we need to enable Form submissions through our app's dashboard on Netlify.
When that's done, we're ready to receive form submissions, but we have to create our form first. We'll be creating a contact form where our visitors can enter their name, email address, and a message.
Start with the form in index.html
Since Angular is a single page application, our main form will be created at runtime. Netlify is not able to detect our form made with Angular, and we therefore need to create a form on the page we’re always loading, which is
index.html. Most Angular apps hosted on Netlify will redirect all traffic to
index.html, let Angular bootstrap, and then the app will take care of the routing. Netlify only sees our
index.html file (before Angular bootstraps,) and that’s why we include our hidden form there. Don’t worry about duplicating a lot of code, we only add the inputs with the same names as we use for our Angular form.
<body> <app-root></app-root> <!-- Hidden form used for Netlify Forms to pick it up --> <form name="contact" method="POST" netlify hidden> <input type="hidden" name="form-name" value="contact" /> <input type="hidden" id="name" name="name" /> <input type="hidden" id="email" name="email" /> <textarea type="hidden" id="body" name="body"></textarea> </form> </body>
We need to add
type="hidden" to prevent displaying the form, because we only want Netlify’s bot to recognize it, not our visitors. Remeber to also add the
netlify attribute, and an input filed which is used by Netlify to determine which form we are submitting:
<input type="hidden" name="form-name" value="contact" />
This field is not something the user will see nor interact with, but it’s important to include it when we submit our form. If we don’t include it, Netlify won’t be able to receive the form submission.
Let’s add our contact form to Angular
Next up is creating our actual form the user will see and interact with. You can add it to any page you already have, or create a new page. We’ll be using a new component,
ContactComponent, and create a reactive Angular form with some simple, but important, validation. I have omitted styling (css) from this tutorial, but we'll end up with something similar to this form, which is the same form I have on my home page, https://reitgames.com/contact. The form on my page is made exactly the same as we’ll do in this blog post.
I personally like to send the form manually, with code, because I’m able to redirect the user to a different page after the form is sent, or conditionally display a message, snackbar, modal, or any other kind of essential feedback to the user. In this tutorial, we’ll hide the form, and display a "thank you message," after the form is submitted.
<div> <div *ngIf="isContactFormSubmitted"> Thank you for reaching out! Your message has been successfully sent. I'll get back to you as soon as I can. </div> <form *ngIf="!isContactFormSubmitted" name="contact" [formGroup]="contactForm" method="POST" (ngSubmit)="onSubmit($event)" netlify> <!-- This input field is very important to add, at least when we submit the form, making sure Netlify can receive the submission --> <input type="hidden" name="form-name" value="contact" /> <label for="name">Name</label> <div *ngIf="name && name.invalid && (name.dirty || name.touched)" class="alert alert-danger"> <small *ngIf="name.errors?.['required']">Name is required</small> </div> <input id="name" type="text" formControlName="name" required /> <label for="email">Email</label> <div *ngIf="email && email.invalid && (email.dirty || email.touched)" class="alert alert-danger"> <small *ngIf="email.errors?.['required']">Email is required</small> <small *ngIf="email.errors?.['email']">Enter a valid email address</small> </div> <input id="email" type="email" formControlName="email" required /> <label for="body">Message</label> <div *ngIf="body && body.invalid && (body.dirty || body.touched)" class="alert alert-danger"> <small *ngIf="body.errors?.['required']">Message is required</small> </div> <textarea id="body" type="text" rows="4" cols="50" formControlName="body" required></textarea> <button type="submit" [disabled]="!contactForm.valid">Send message</button> </form> </div>