All posts
Web design & development

Forms, Integrations and APIs on Next.js Marketing Sites

Next.js forms integration done properly: server actions, spam protection, CRM sync with HubSpot and others, and conversion tracking that matches your leads.

By Mehdi Hassan7 min read

The short answer

A solid Next.js forms integration posts each form to a server action or route handler, validates it, blocks spam with a honeypot and a challenge such as Turnstile, then sends the lead to your CRM through its API and fires one conversion event on success. Handling all three on the server keeps leads, spam and analytics consistent.

Key takeaways

  • Submit forms to your own server code first, then fan out to the CRM, email and analytics.
  • Combine a honeypot, a challenge like Turnstile and rate limiting; no single layer stops all spam.
  • Use the CRM's submission API, not an embed, when you care about speed and design.
  • Fire the conversion event only after the server confirms the lead was saved.
  • Log every submission somewhere you own, so a CRM outage never loses a lead.

Part of Next.js for Marketing Websites: When It's the Right Choice

How do you connect forms on a Next.js marketing site?

You connect forms on a Next.js marketing site by posting them to your own server code, a server action or a route handler, which validates the data and then sends it on to your CRM, your inbox and your analytics. The browser never talks to the CRM directly, so API keys stay private and every lead passes the same checks.

This is one of the practical advantages of a coded site over a builder, and it's a big part of why teams pick Next.js for a marketing website in the first place. The trade-off is that someone has to build what a builder gives you for free: validation, spam protection, notifications and retries. This guide covers all of it in one flow, because those pieces fail together when they're built separately.

Should you embed the CRM form or build a custom one?

Build a custom form that submits through the CRM's API if design, speed and data control matter to you. Use the CRM's embed only when you need its built-in features, like progressive profiling, and accept the extra script weight.

Approach

Design control

Page weight

Spam control

Best for

CRM embed script

Limited, styled with overrides

Heavy third-party script

The CRM's own

Teams that rely on CRM form features

Custom form + CRM API

Full

Minimal

Yours, layered

Most marketing sites

Custom form + form service

Full

Minimal

The service's plus yours

Small sites without a CRM

Custom form + automation tool

Full

Minimal

Yours

Routing leads to several tools

Third-party form embeds are also a common source of slow interactions, which our guide to Core Web Vitals on Framer, Webflow and Next.js covers. If you're moving off a builder's native forms, see what replaces Webflow forms in Next.js.

What are the steps for a Next.js forms integration?

The reliable pattern has seven steps, and the order matters: validate and save before you send anything anywhere else.

  1. Build the form as a progressive enhancement

    Use a normal form element that posts to a server action, so it still submits if JavaScript is slow. Add client-side validation only as a convenience.

  2. Validate on the server

    Check every field with a schema library such as Zod. Reject unexpected fields, enforce lengths and normalize emails before anything else runs.

  3. Run spam checks

    Check the honeypot field, verify the challenge token with the provider, and apply a per-IP rate limit. Fail quietly for bots and clearly for humans.

  4. Save the submission

    Write the lead to a store you own, such as your CMS, a database table or a log, with a status field. This is your safety net.

  5. Send it to the CRM

    Call the CRM's API with the mapped fields plus context like page URL and UTM parameters. Mark the saved record as synced or failed.

  6. Notify the team

    Send an internal email or chat message through a transactional email service with proper domain authentication.

  7. Confirm and track

    Return success to the browser, show a clear confirmation, and only then push the conversion event.

How do you stop form spam without hurting real users?

Stop form spam with layers, because each layer catches a different kind of bot. A honeypot, a low-friction challenge and rate limiting together block most automated spam without making humans solve puzzles.

  • Honeypot field. A hidden input that humans never fill. Any submission with a value is dropped. It costs nothing and catches simple bots.
  • Invisible or managed challenge. Cloudflare Turnstile or reCAPTCHA issues a token in the browser that your server verifies. Load the script only on pages with forms.
  • Rate limiting. Limit submissions per IP and per email over a short window, at the edge or in your server code.
  • Content checks. Reject links in name fields, disposable email domains if you sell to businesses, and messages that are only URLs.
  • Time check. Forms submitted within a second or two of page load are almost always automated.

Never rely on client-side checks alone. Bots post straight to your endpoint, so every rule has to run on the server.

How do you sync leads to HubSpot or another CRM?

Sync leads by mapping your form fields to the CRM's fields and calling its submission or contacts API from the server. Include the page URL, page title, UTM parameters and, for HubSpot, the tracking cookie value, so attribution survives even though you're not using the embed.

Two details save a lot of pain. First, keep the field mapping in one config file so marketing can add a field without hunting through code. Second, decide what happens when the CRM is down: retry with a queue, or mark the saved record as failed and alert someone. If HubSpot also runs your content, our guide to HubSpot CMS to Next.js explains how the custom front end and HubSpot back office fit together.

Hypothetical example: a demo request flow with routing

For example, suppose a B2B startup has one demo form with company size as a field. The server action validates the form, checks Turnstile and saves the lead. It then creates or updates the contact in the CRM, sets the lifecycle stage and owner based on company size, and posts a message to the sales channel with the lead's details.

If the CRM call fails, the lead stays in the saved log with a failed status, a scheduled job retries it, and the team is alerted after a second failure. The visitor sees the same confirmation either way, because their request was received.

How do you track form conversions accurately?

Track form conversions by pushing one well-named event, such as generate_lead, to the data layer after the server confirms success, with the form name and page as parameters. Tag managers and ad platforms then read that single event.

Respect consent: the event fires either way, but your consent setup decides what each tag may store. For high-value forms, send the conversion server-side as well, so ad blockers don't hide it. Our guide to conversion tracking for lead-gen websites covers naming, deduplication and reporting in detail.

Why are form notification emails not arriving?

Form notification emails usually fail because the sending domain isn't authenticated, so inbox providers treat them as spoofed. Send through a transactional email service and set up SPF, DKIM and DMARC for the domain you send from.

Also avoid sending from the visitor's address, which fails authentication by design; put it in the reply-to header instead. Our guide to email deliverability for website forms walks through each record. Finally, host the endpoint somewhere predictable: our notes on hosting Next.js on Cloudflare Workers cover environment secrets and runtime limits that affect form handlers.

Frequently asked questions

Are server actions safe for public forms?
Server actions are safe for public forms if you treat them like any public endpoint. Anyone can call them, so validate every field on the server, verify the spam challenge, apply rate limits and never trust hidden fields for pricing or permissions. The convenience of server actions doesn't remove the need for the same checks a route handler would have.
Do I need a database just for form submissions?
You need somewhere you own to store submissions, but it doesn't have to be a dedicated database. A collection in your headless CMS, a simple table on your host or even a structured log works. The point is that a lead is never lost because a CRM call failed or an email bounced. You can then retry or export from that record.
Is Cloudflare Turnstile better than reCAPTCHA?
Both work. Turnstile is often chosen for marketing sites because it usually runs without asking people to solve image puzzles and doesn't depend on Google. reCAPTCHA is familiar and widely supported. Whichever you choose, verify the token on the server, load the script only on pages with forms, and pair it with a honeypot and rate limiting.
Can marketing add new form fields without a developer?
Yes, if the form is built from a schema defined in the CMS or a config file. Editors add a field, choose its type and map it to a CRM property, and the form and validation update together. Without that setup, every new field needs a code change, which is fine for sites that rarely change their forms.
How do I pass UTM parameters into the CRM?
Capture UTM parameters from the landing URL when the visit starts, store them in a first-party cookie or session storage, and include them as hidden values when the form submits. The server action then maps them to CRM properties. Capturing on first landing matters, because visitors often browse several pages before converting.

· CEO & Design Director

Copywriter, designer and developer, and founder of Designify Studio. Over five years, 60+ projects across 14+ industries, for startups that have raised $300M+.

Want this done for you? Website, $8,000.

A multi-page marketing site, designed by us, developed in Next.js and animated. $8,000, one-time, up to 6 pages. Book a free 30-minute call to see if it fits.

Schedule Call