New: Introducing the Forminit Python SDK ->
Back to all posts

Multi-Step Forms with File Upload in Framer (No Plugin)

By Forminit in Recipes • Published May 14, 2026

How to build multi-step forms with file upload in Framer using Forminit

Framer native form doesn’t support file uploads, multi-step flow, or custom design. The fix is a single HTML embed. Ask any AI assistant to generate the form, paste it into Framer through Insert → Embed, and you’re done.


Why Framer’s native forms aren’t enough

Framer is one of the best design tools on the web. Native forms are the part that hasn’t caught up. If you’ve tried to build anything more complex than a name-and-email contact form in Framer, you’ve hit the wall:

  • No custom design or flow. You’re stuck with Framer’s form props. Fonts, spacing, layouts, the order of fields, the way validation looks, all locked into the same template. With a custom HTML embed wired to Forminit, your imagination is the limit.
  • No file uploads. You can’t collect a resume, a brief, a mood board, or any other attachment. Submissions are text-only.
  • No multi-step flow. Everything is one screen. There’s no built-in way to split a long form into “Step 1 of 4” with a progress indicator.
  • Very limited field types. Text, email, basic select. No proper file input, no rating, no E.164 phone validation, no country dropdown, no rich date picker.
  • No conditional logic. You can’t show or hide fields based on previous answers.
  • No form analytics. You see what someone typed, but not the campaign that brought them, the country or device they came from, or how the rest of your audience is answering your radio, select, and checkbox fields. Every lead lands without context.
  • No UTM or click ID auto-capture. If you’re running Google Ads, Meta Ads, TikTok, or LinkedIn campaigns, the gclid, fbclid, msclkid, and ttclid parameters aren’t attached to submissions automatically. You can’t tell which campaign produced which lead.
  • No real submission management. No starring, no status tracking, no internal notes, no full-text search across all submissions, no field-level filtering, no CSV export.
  • No real integrations. Out of the box you’re tied to Framer’s email destination. Anything beyond that (Slack, Discord, Zapier, webhooks to your CRM) is on you.

The usual workaround is to pay for a Framer-specific form plugin and a separate form backend on top. That solves part of the design problem and stacks two more subscriptions on top of your Framer plan. It also keeps the form locked inside another vendor’s component system, which means you can’t take it with you if you ever move off Framer.

The fix: one custom HTML embed inside Framer

Framer’s Embed element accepts any block of HTML, CSS, and JavaScript and renders it as part of your page. That’s the workaround for every native form limitation. You bring a custom HTML form. Framer just displays it.

The catch has always been: “I’m a designer, I don’t write HTML forms by hand.” That’s no longer true. Any AI assistant (Claude, ChatGPT, Cursor, v0) can produce a production-ready multi-step form in one prompt. You point it at form backend Forminit so submissions land in a real inbox with analytics, file uploads, UTM tracking, and integrations.

The end result inside Framer:

  • A form built to your exact needs
  • A multi-step form with a progress bar
  • File uploads up to 25 MB per submission
  • Pixel-matched to your Framer site
  • Submissions in a searchable inbox with full-text search and per-field filters
  • UTM parameters and ad click IDs captured automatically
  • Slack, Discord, Zapier, and webhook integrations out of the box
  • No plugin to install in Framer

Steps

Integration is very basic, under 1 minute:

  1. Create a Forminit account for free and create a form. Copy the Form ID.
  2. Open your favourite AI assistant (ChatGPT, Claude, Cursor, v0). Describe the form you want and connect it to your Forminit form.
  3. In Framer: Insert → Embed → paste the HTML. Publish.

That’s the whole integration. The detailed walkthrough with the exact prompt is below.

How the integration works

Here are the three steps in detail. The middle one is the only one that takes any real work, and an AI assistant does it for you.

Step 1: Create your Forminit form

  1. Sign up at forminit.com. The Free plan covers 50 submissions/month and includes file uploads.
  2. Create a new form, name it something like “Sales Inquiries” or “Job Applications”.
  3. Go to Form Settings and leave authentication mode as Public. This is correct for client-side forms inside Framer.
  4. Copy your Form ID. It looks like abc12def-3456-....

That’s the entire dashboard side. From here, every submission you collect lands in your Forminit inbox.

Step 2: Generate the HTML form with AI

Open Claude, ChatGPT, Cursor, v0, or any LLM you like. The prompt has two parts: the placeholders you fill in, and the prompt body itself.

Placeholders to replace

PlaceholderReplace with
[WEBSITE_URL]The URL of your live Framer site (or a staging URL)
[FORMINIT_FORM_ID]The Form ID you copied in Step 1

Example prompt

Analyze this website design and build a matching responsive
multi-step SALES contact form for Framer Embed: [WEBSITE_URL]

Connect it to Forminit using form ID: [FORMINIT_FORM_ID]

Use this integration guide:
https://forminit.com/skills/forminit-html/SKILL.md

Return a single production-ready HTML snippet with inline
CSS and JS only.

Requirements:
- Multi-step SALES inquiry form (real customer lead flow)
- Step 1: Company and name
- Step 2: Email and phone
- Step 3: Project details (budget, timeline, service type)
- Step 4: File upload (brief, documents, assets)
- Step 5: Review and submit
- File upload must support multiple files and integrate with Forminit fields

You can adapt the same prompt to any use case: job applications with resume uploads, photography session inquiries with reference image uploads, agency briefs with PDF attachments, real estate enquiries with document uploads, freelance project requests with mood boards. The structure stays the same. Describe the steps, list the fields, point at the skill guide, paste the Form ID.

Step 3: Paste into Framer

Open your Framer project and do this:

  1. Open the page where you want the form
  2. Click Insert, search for Embed, drag it onto the canvas
  3. In the right-hand properties panel, paste the entire HTML snippet your AI assistant produced
  4. Resize the embed frame to fit your layout
  5. Publish

That’s the whole integration. The form is now live on your Framer site, styled to match it, multi-step, with working file upload.

What happens after the first submission

The moment someone hits submit, here’s what happens automatically. None of this needs wiring up:

  1. Server-side validation of every field using typed blocks (email format, E.164 phone, file MIME type, file size)
  2. Storage in your inbox with a unique ID, timestamp, and full field structure
  3. Email notification to whoever you’ve configured in the form settings
  4. Autoresponder to the submitter if you have it enabled (Business plan)
  5. Attribution capture: UTM parameters (utm_source, utm_medium, utm_campaign, utm_term, utm_content), ad click IDs (gclid, fbclid, msclkid, ttclid, twclid, LinkedIn, Amazon, Mailchimp), referrer URL, and geolocation (country, city, timezone) from the submitter’s IP
  6. File storage on encrypted AWS infrastructure in Ireland (EU), accessible via direct download URLs in your dashboard
  7. Forwarding to Slack, Discord, Zapier, Make, or any webhook URL you’ve configured
  8. Spam protection: reCAPTCHA v3, hCaptcha, honeypot, or all three combined

In the dashboard you can filter submissions by date, by field value (e.g. all submissions with budget = $50K+), by status, by tag, or full-text search across every field at once. You can star important leads, mark them open / in-progress / done / cancelled, add internal notes that the submitter never sees, and export everything as CSV.

The analytics page gives you a field-level breakdown for every radio, select, and checkbox field. If you have a “How did you hear about us?” radio in your form, the analytics page automatically shows you that 42% came from Google, 28% from Twitter, 18% from referrals, and so on. Counts and percentages, no spreadsheet required.

A note on file uploads

File upload is the single feature that breaks most Framer form workflows. Native Framer forms don’t support it. Most plugins either don’t, or send the file as a URL link rather than as an actual upload tied to the submission.

The embedded form handles file uploads as a first-class field. In your HTML:

<input type="file" name="fi-file-brief" multiple
       accept=".pdf,.doc,.docx,.png,.jpg,.zip" />

The fi-file-{name} naming is what tells the backend this is a file field. Multiple files are supported per field, total payload up to 25 MB, with 50+ MIME types allowed (PDF, DOC, DOCX, XLS, XLSX, PNG, JPG, GIF, WebP, SVG, ZIP, and more). Files appear in the dashboard alongside the rest of the submission, with direct download URLs. This works on the Free plan.

Page speed: no impact on your Framer site

Framer sites tend to score well in Lighthouse and Google Search Console Core Web Vitals. A third-party form widget can wreck that. The embed described in this guide does not.

Here’s why:

  • No third-party widget loading external scripts from another domain
  • No iframe with vendor branding and its own asset bundle
  • No tracking pixel or analytics beacon
  • No heavy JavaScript injected into the page. The optional Forminit SDK is only 2 KB, loaded once
  • The form itself is plain HTML, CSS, and JS that you paste in directly

Your Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP) scores stay untouched. The submission only fires when someone actually submits the form. Nothing runs in the background, nothing phones home on page load, and nothing blocks rendering. This matters specifically for Framer sites, where design and performance are part of the value proposition.

Going further

Run different forms on different pages

Create one form per use case (Sales Inquiries, Job Applications, Press Requests) and paste a different embed on each Framer page. Each one has its own dashboard, its own notification settings, its own webhook integrations. Cleaner than dumping everything into one inbox.

Send leads straight to your CRM

Under Integrations → Webhooks in your form settings, paste your CRM’s incoming webhook URL (HubSpot, Pipedrive, Attio, anything that accepts a POST). Every submission gets forwarded as structured JSON in real time. You can also use Zapier for no-code routing to 5,000+ apps.

Match the form to your design system

Once your AI assistant has produced the HTML, paste it into Claude or ChatGPT again with: “Restyle this form to match the design tokens of [my Framer site URL]: same fonts, same primary color, same border radii, same input heights. Keep all the field names and JavaScript identical.” The visual fidelity gets very close to native very quickly.

Add reCAPTCHA without changing anything

In your form settings, toggle reCAPTCHA v3 on and paste your Google site key. That’s it. The JavaScript SDK in your embed picks it up. No code changes in Framer.

Pre-fill fields from URL parameters

If you run paid ads with ?plan=pro&source=google, you can have your form auto-fill the plan field on load. The skill guide includes a pattern for this. Combined with auto-UTM capture, you get full campaign-to-conversion tracking without an analytics platform.

Frequently asked questions

Do I need a Framer plugin to use this approach?

No. The integration is a plain HTML/CSS/JS snippet pasted into Framer’s built-in Embed element. There is no Framer-specific plugin to install, no extension to approve, no marketplace purchase. The same approach works on Webflow, Carrd, Squarespace, WordPress, plain HTML, or any other host that accepts an embed.

Does Framer’s native form support file uploads?

No. As of May 2026, Framer’s native form does not support file uploads. To collect files in a Framer site, you either use a plugin, embed a third-party form, or use the approach in this guide: a custom HTML form with a backend (Forminit) handling the file storage. Forminit supports uploads up to 25 MB across 50+ MIME types on every plan, including the Free plan.

Can I build a multi-step form in Framer without code?

Framer’s native forms don’t support multi-step flow. You can fake it with multiple pages and conditional navigation, but you lose the form state between pages. The cleanest answer is a custom HTML form generated by an AI assistant and embedded. The form state, step navigation, progress bar, and validation all live inside the single embed. The form backend handles submissions.

Will the embed slow down my Framer site or hurt my Google Search Console scores?

No. Forminit has no heavy JavaScript injects to your page. There’s no third-party widget, no iframe, no tracking pixel, and no analytics beacon. The only script involved is an optional 2 KB SDK loaded once. The form itself is plain HTML, CSS, and JS that you paste in directly. Your Lighthouse, Core Web Vitals, LCP, CLS, and INP scores in Google Search Console stay the same. Submissions only fire on submit, not on page load.

Will the form look like part of my Framer site?

Yes. Because the form is your own HTML and CSS, you have pixel-level control over fonts, colors, spacing, border radii, and animations. The AI prompt at the top of this post explicitly asks the assistant to analyze your site’s design and match it. If it doesn’t match perfectly on the first pass, ask the AI to restyle it using your design tokens.

Does Forminit auto-capture UTM parameters and ad click IDs?

Yes. Forminit’s JavaScript SDK automatically captures all five UTM parameters (utm_source, utm_medium, utm_campaign, utm_term, utm_content) plus ad platform click IDs from Google (gclid), Meta (fbclid), Microsoft (msclkid), TikTok (ttclid), X (twclid), LinkedIn, Amazon, and Mailchimp. Referrer URL and geolocation (country, city, timezone) are also captured automatically. The skill guide tells the AI to include the SDK in the embed, so this works out of the box.

Can I search and filter through all my Framer form submissions?

Yes. The dashboard provides full-text search across every field in every submission, plus per-field filters (e.g. show me only submissions where budget = $50K+ and service = web design), date range filters, status filters, and tag filters. You can star important submissions, mark them open / in-progress / done / cancelled, and add internal notes that the submitter never sees. All submissions can be exported as CSV on the Pro plan.

Can I use the same form across multiple Framer pages?

Yes. The HTML embed is just a snippet. You can paste it on as many Framer pages as you want, and all submissions land in the same form inbox. If you want separate inboxes per page, create one form per page and paste the matching embed.

How do I add Slack, Discord, or Zapier notifications?

In your form settings, go to Integrations. Connect Slack by pasting an incoming webhook URL for the channel you want notifications in. Discord works the same way. Zapier connects via the official integration and lets you route submissions to any of 5,000+ apps. Generic webhooks fire on every submission and POST the structured submission data to any URL you provide.

What if the AI assistant generates the wrong field names?

The skill guide URL in the prompt (https://forminit.com/skills/forminit-html/SKILL.md) exists specifically to prevent this. It documents the fi-{blockType}-{name} field naming convention so the AI uses fi-sender-email and fi-file-brief rather than email and brief. If you don’t include the skill guide URL, you may end up with generic field names and submissions that arrive empty. Always include it.

Can I switch from FramerForms, Tally, or Typeform without losing data?

Yes, going forward. Create a new form, generate a matching HTML embed, replace the old form on your Framer site, and new submissions start flowing into Forminit immediately. Historical data stays in your previous tool. If you need help migrating, contact info@forminit.com.

Does this work with Framer’s CMS or dynamic pages?

Yes. The embed is a self-contained HTML block. It doesn’t care whether the page is static, a CMS template, or a dynamic route. You can also pass values from Framer into the form via URL parameters (e.g. pre-filling a productId field on a CMS detail page) and the backend will store them with the submission.

Is Forminit GDPR-compliant for EU Framer sites?

Yes. Forminit (UXPLUS LTD, UK Company #11357429) is GDPR-compliant under both UK and EU GDPR, registered with the UK ICO, and stores all submission data on AWS servers in Ireland (EU). A Data Processing Agreement (DPA) is available. This matters specifically because some Framer form plugins are not officially acting as processors under GDPR Article 28 and do not offer a DPA.

Framer native vs Framer + a custom embed

A side-by-side reference for what you gain by switching from Framer’s built-in form to a custom HTML embed wired to Forminit:

What you wantFramer native formFramer + custom embed
Multi-step flow with progress barNot supportedYes, any number of steps
File uploads (resumes, briefs, images)Not supportedUp to 25 MB, 50+ file types
Custom design pixel-matched to your siteLimited by Framer’s form propsFull HTML/CSS/JS control
Conditional logic (show/hide fields)Not supportedYes, in your own HTML/JS
Field-level analytics (radio/select breakdowns)NoYes
Submission inbox with search and filtersNoYes, full-text search and per-field filters
Status tracking, starring, internal notesNoYes
CSV exportNoYes
UTM auto-captureNoYes
Ad click IDs (gclid, fbclid, msclkid, ttclid, twclid)NoYes
Slack / Discord / Zapier / WebhooksLimitedAll included
Spam protection (reCAPTCHA v3, hCaptcha, honeypot)BasicAll three supported
Autoresponder to submitterNoYes
Free planLimited submissions on Framer plan50 submissions/month free, file uploads included

Further reading