How to Connect Ninja Forms to Google Sheets

Send Ninja Forms submissions to Google Sheets with a direct plugin connection. No Zapier subscriptions, no middleware services, no per-submission fees. Works with free and paid Ninja Forms.

Last updated: 2026-03-13 6 min read

TL;DR

Install SheetLink Forms, deploy a Google Apps Script webhook, paste the URL in SheetLink settings, map your Ninja Forms fields, and test. About 5 minutes. Works with the free version of Ninja Forms.

Ninja Forms is a drag-and-drop WordPress form builder with over 800,000 active installs. It's free on WordPress.org, with a flexible Pro ecosystem of paid addons for specific integrations. But Google Sheets isn't among those addons - there's no first-party Ninja Forms Sheets integration at any price.

The Ninja Forms team's official recommendation is to use Zapier. That works, but it means paying Zapier's per-task fees (currently $29.99/month and up) and running your form data through a third-party server. For teams that want a simpler, cheaper, more direct path - form submits, Google Sheet updates, no middleware - there's a gap to fill.

SheetLinkWP fills it. It hooks into Ninja Forms' native action system (the same architecture Ninja Forms uses for its own email, webhook, and redirect actions) and delivers submissions directly to Google Sheets via an Apps Script webhook. This guide walks through the setup, explains the Ninja Forms-specific quirks (field keys vs field IDs, action order, multi-step forms, conversational mode), and shows the realistic configurations Ninja Forms users need.

Why Ninja Forms Users Pick Google Sheets

Ninja Forms stores submissions in WordPress through a custom post type (nf_sub). That's functional for small sites, but it's not built for reporting - searching, filtering, and exporting at scale is clunky, and sharing data with non-admin team members requires giving them WP admin access.

A Google Sheet gives you everything that's missing: sortable columns, shareable with specific email addresses, live pivot tables, and compatibility with Looker Studio dashboards. For Ninja Forms users especially, Sheets is often the first real database the form data has ever been in. Instead of opening the Ninja Forms submissions table and scrolling, you open a familiar spreadsheet and filter.

SheetLinkWP uses the same action-based pattern Ninja Forms uses for everything else. If you're used to configuring email actions, webhook actions, or user-registration actions, the SheetLinkWP delivery feels native - it's just another action firing when submissions succeed.

How SheetLinkWP Integrates With Ninja Forms

Ninja Forms' processing pipeline is built on numbered action priorities. Every output (email, redirect, save submission) is an action with a priority. SheetLinkWP registers as an action that fires after validation and after submission save:

  1. 1. Form submitted, validation runs: Ninja Forms validates required fields, custom validators, and reCAPTCHA. Only valid submissions proceed.
  2. 2. Save Submission action fires: Ninja Forms stores the submission in the nf_sub custom post type. This runs at priority 10.
  3. 3. SheetLinkWP action fires: SheetLinkWP's Google Sheets action runs at priority 20, after save and after email delivery. It has full access to the submission ID and field values.
  4. 4. Field keys resolved to values: Ninja Forms uses named field keys (e.g., name_1, email_2). SheetLinkWP maps these keys to your configured columns.
  5. 5. Enrichment data added: UTM parameters, click IDs, submission timestamp, IP, user agent, and referring URL join the payload if enabled.
  6. 6. Webhook POST to Apps Script: A JSON payload is sent to your Apps Script endpoint. On failure, the submission is queued for retry with exponential backoff.

What You Need

  • A WordPress site with Ninja Forms installed (free or premium) and at least one form
  • A Google account with access to Google Sheets
  • SheetLink Forms plugin (free tier or any paid license)

Step-by-Step Setup

Field mapping tip: Ninja Forms uses field keys like "name", "email", "message" (or custom keys you set). SheetLinkWP reads these keys and shows the corresponding labels. If you've customized field keys, those custom keys appear in the mapping interface.
  1. 1

    Create your Google Sheet

    Open Google Sheets and create a new spreadsheet. Name it descriptively. Leave it blank - SheetLinkWP auto-generates column headers from the first submission.

  2. 2

    Deploy the Apps Script webhook

    In your Sheet, go to Extensions > Apps Script. Paste the SheetLinkWP receiver script, deploy as a Web app with "Anyone" access, and copy the deployment URL.

  3. 3

    Install SheetLink Forms

    Download from sheetlinkwp.com or WordPress.org. Upload via Plugins > Add New > Upload Plugin. Activate the plugin.

  4. 4

    Connect the webhook

    Go to SheetLink > Settings, paste your Apps Script URL, and save.

  5. 5

    Map Ninja Forms fields

    Navigate to SheetLink > Field Mapping. Select "Ninja Forms" as the form plugin and choose your form. SheetLinkWP detects all Ninja Forms field keys and displays labels alongside them. Map each field to a Sheet column.

  6. 6

    Test the connection

    Submit a test entry through your Ninja Forms form on the front end. Check Google Sheets for the new row within a few seconds.

Ninja Forms Field Key & Meta Reference

Ninja Forms identifies fields by developer-friendly string keys you set when designing the form. Each field also has a numeric ID, but keys are what you map in SheetLinkWP because they're stable across form duplications and imports. Ninja Forms also exposes submission-level metadata you can pull in directly:

Field key / meta Source Notes
name_1 Default name field Standard single-line text for visitor's name. Key defaults to name_1 but can be renamed to any string.
email_1 Default email field Validated as email by Ninja Forms. Invalid submissions never reach SheetLinkWP.
message_1 Default message field Textarea. Ninja Forms does not impose a length limit - SheetLinkWP writes up to 50,000 characters per Sheet cell.
your-custom-key Any text, email, URL, number, date, or hidden field Whatever string you set in the field's "Administration > Key" setting. Recommend sluggy lowercase_with_underscores.
checkbox_1 Checkbox group Multi-checked values join with commas. Single checkbox writes 1 or 0.
list_dropdown_1 Single-select dropdown Writes the selected option value (not the label) unless the option defines both.
list_multi_select_1 Multi-select list Values join with commas. Consider splitting into one checkbox per column for response-frequency analysis.
file_upload_1 File upload Requires the File Uploads addon. Writes the uploaded file URL. Pair with the SheetLinkWP Drive add-on to mirror files into a Google Drive folder.
_submission_id Submission meta Ninja Forms submission post ID. Permanent, unique. Use as Sheet primary key.
_date_submitted Submission meta Timestamp in site timezone.
_form_id Submission meta Numeric Ninja Forms form ID. Handy for multi-form Sheets filtering.
_form_title Submission meta Form name as set in the Ninja Forms editor.
_ip_address Submission meta Visitor IP. Empty if Ninja Forms' IP logging is disabled.
_user_agent Submission meta Browser user agent string. Useful for mobile/desktop segmentation.
_referrer Submission meta HTTP referer - the page the visitor came from.
_page_url Submission meta Full URL of the page containing the form (with query string).
_user_id Submission meta WordPress user ID if the submitter is logged in, otherwise 0.

Real-World Use Cases

Replace the deprecated Save Submissions workflow

Ninja Forms' "Save Submissions" action stores entries inside WordPress, which becomes unwieldy at thousands of entries and makes sharing data outside the WP admin painful. A Google Sheet is faster to open, faster to search, and can be shared via email with a click.

Field mapping: Map all your form's field keys plus _submission_id, _date_submitted, and _page_url. Keep the native Save Submissions action on for 30 days as a fallback, then disable it to keep the DB lean.

Conversational Form mode with complete payload capture

The Conversational Forms addon presents Ninja Forms one-field-at-a-time, chat-style. It still fires the same submission hooks, so SheetLinkWP captures the complete response after the final field - no partial conversations lost mid-way.

Field mapping: Standard field keys, plus _page_url and a hidden conversion_source field you set via URL parameter. Conversational Forms' dropout analytics stay in Ninja Forms; completed conversations land in the Sheet.

Multi-language Ninja Forms (WPML / TranslatePress)

When the same form is shown in English and Spanish via a translation plugin, submissions carry identical field keys but different page contexts. Pull _page_url and _form_title to disambiguate, and segment via Sheet formulas.

Field mapping: All field keys + _page_url, _form_title. Sheet formula: =IF(ISNUMBER(SEARCH("/es/", E2)), "Spanish", "English").

Wholesale application form with scoring

A B2B form captures business type, order volume, and industry. You want automatic lead qualification: rows with volume > 500 get flagged as priority. SheetLinkWP writes the raw submission; Sheet formulas handle scoring. No Ninja Forms addon needed.

Field mapping: Map business_name, contact_email, business_type, annual_volume fields. Sheet formula column: =IF(G2>500, "Priority", "Standard"). Sort newest-to-oldest, pin Priority rows with conditional formatting.

Advanced Tips

Always use custom field keys, not defaults

Ninja Forms auto-assigns keys like textbox_1 if you don't set one. That's fragile - if you duplicate the form or the IDs shift, your mappings break. In the field's Administration tab, set a human-readable key (business_email, annual_revenue) once and it survives every form edit forever.

SheetLinkWP runs at priority 20 - after email

By design, SheetLinkWP fires after Ninja Forms' native email action. This means if an email fails to send (misconfigured SMTP, etc.), your Sheet delivery is unaffected. If you need Sheet delivery to happen first (to set a follow-up flag on the Sheet row that the email can then reference), change the action priority in SheetLink > Settings > Ninja Forms.

Use submission ID for idempotent webhooks

Map _submission_id to column A. If a retry results in a duplicate delivery (rare, but possible during network instability), Apps Script's receiver can check for an existing row with that submission ID and update rather than append. The SheetLinkWP Apps Script template includes opt-in dedupe logic for this case.

Works with the Multi-Part Forms addon

Ninja Forms' Multi-Part addon splits long forms into pages. SheetLinkWP captures the complete submission after the final page, so all fields from all pages arrive in one Sheet row. Partial submissions (abandoned mid-form) aren't written by default - enable "Capture partial submissions" in settings to route them to a separate tab.

Coexist with Ninja Forms Excel / CSV exports

If you already use Ninja Forms' built-in CSV export to feed an external system, you can keep that workflow running. SheetLinkWP adds live delivery without touching your export pipeline. Many teams start with dual-path - CSV weekly, Sheet continuously - and drop CSV once the Sheet has proven itself.

Troubleshooting

Ninja Forms submissions don't arrive in Google Sheets

Check SheetLink > Delivery Log. Ninja Forms processes actions asynchronously - ensure no other Ninja Forms action is conflicting. Re-deploy the Apps Script webhook if needed.

Multi-part fields show unexpected values

Ninja Forms handles some complex fields differently than other plugins. Check that the field key in SheetLink matches what Ninja Forms actually submits. Use the Delivery Log to see the raw payload.

Custom field keys I set don't appear in SheetLink's mapping UI

Clear the Ninja Forms cache. After changing field keys, Ninja Forms caches form structure for performance - SheetLinkWP reads from that cache. Go to Ninja Forms > Submissions, open any submission, and close it to force a cache refresh. Then return to SheetLink > Field Mapping.

Action priority conflict with another addon

Some third-party Ninja Forms addons register actions at priority 20, same as SheetLinkWP. If their action depends on SheetLinkWP output (unlikely) or vice versa, change SheetLinkWP's priority in Settings. Priorities 21-29 are safe.

File upload URLs are broken in the Sheet

Ninja Forms' File Uploads addon stores files in <code>/wp-content/uploads/ninja-forms/</code>. The URLs SheetLinkWP writes are absolute and public by default. If your site enforces login to access uploads, the URLs won't work for Sheet viewers without WP accounts - enable the SheetLinkWP Drive add-on to mirror files into a Google Drive folder instead.

Ninja Forms to Google Sheets: How to Connect

FeatureZapierCustom WebhookSheetLinkWP
Monthly cost (500 subs) $29.99+/mo$0 + dev time$0 (one-time $39)
Per-submission fee YesNoNo
Setup complexity MediumHigh (coding required)Low (~5 min)
UTM capture Extra stepsManualAutomatic
Retry on failure Auto-retryYou build itBuilt-in queue
Works with Ninja Forms Free YesYesYes

Frequently Asked Questions

Does SheetLinkWP work with the free version of Ninja Forms?

Yes. SheetLinkWP works with both the free and premium versions of Ninja Forms.

Why doesn't Ninja Forms have a native Google Sheets integration?

Ninja Forms offers Zapier as their recommended path for Google Sheets connections. There is no built-in addon or native integration. SheetLinkWP fills this gap with a direct connection.

Can I use SheetLinkWP alongside Ninja Forms email actions?

Yes. SheetLinkWP operates independently of Ninja Forms' action system. Your email notifications and other actions continue to work normally.

Does SheetLinkWP support Ninja Forms' multi-step forms?

Yes. SheetLinkWP captures the complete submission after all steps are completed.

Will this work with the Conversational Forms addon?

Yes. Conversational Forms still fires the same submission hooks when the conversation completes. SheetLinkWP writes the full payload just like a traditional form.

Can I use this to replace my CSV export workflow?

Yes. A live-updating Google Sheet is usually a cleaner replacement for manual CSV exports. Many teams run both in parallel for a few weeks then retire the CSV cadence.

Does SheetLinkWP hook before or after email delivery?

After, by default. This means a failed SMTP doesn't prevent your Sheet row from being written. You can change the action priority in SheetLink > Settings if you need Sheets delivery to run before email.

Are hidden fields captured?

Yes. Hidden fields (with or without default values) are treated like any other field and can be mapped to Sheet columns.

Related How-To Guides

Connect Ninja Forms to Google Sheets - Direct, No Zapier

Fill the gap Ninja Forms doesn't - direct Sheets connection, one-time price.