There is a specific email that arrives about three weeks after a site goes live. The client has been clicking around their own contact page and wants to know who Jotform is, and why that name is sitting under the form they paid you to build.
It is not a bug. It is the free tier doing what a free tier exists to do. But it is your problem, because you put it there.
Embedding a form on your own site is well-covered ground. Embedding one on somebody else's site, as part of work they have paid for and will own after you leave, is a different job with different rules.
Your vendor's logo is a bill you are passing to the client
On your own site a small badge is a fair trade for a free tool. On a client's site it is three problems.
Credibility first: a business paying for a professional site reasonably expects its pages not to advertise software it did not choose, and that lands hardest on a quote request or a booking page. Then support — a visible vendor name invites people to search it, find the pricing page, and work out that the form costs nothing.
And the badge is usually a link with a referral parameter attached, so the client's contact page is sending traffic to a company they have no relationship with. None of this is scandalous. It is simply not what they bought.
What each tool charges to take its name off
The prices below were read from each vendor's own pricing page in early October 2026; they change, and vary by region. The pattern is consistent: branding removal is the lever form tools use to move people off the free plan, rarely the top tier or the bottom one.
- Cognito Forms — free Individual keeps the branding; Pro at $24 a month, or $19 billed annually, lists Remove Cognito Forms branding.
- Tally — the free plan keeps the badge; Pro at $29 a month removes Tally branding and adds custom domains; Business is $89.
- Jotform — Starter includes Jotform branding; it is removable from Bronze at $39 a month, or $408 a year. Silver is $49, Gold $129.
- Typeform — not on the entry Basic plan at $39 a month. Branding removal starts at Plus, $79, which adds a custom subdomain; a full custom domain is Enterprise only.
- Formstack — Forms is $99 a month, or $83 billed annually. Its pricing page does not list branding removal at any tier, so treat that as UNCONFIRMED and ask their sales team before quoting.
- Google Forms — no option at any price.
- OneSol — forms embed at /f/<slug>?embed=1, which drops the badge and the surrounding page chrome and leaves the form on its own, themed to the client's colours. We have shipped exactly this into a live client site.
Price it per client, not per tool
Thirty-nine dollars a month is nothing on one project and a real line item across twelve. Most tools price per account, not per form, so the question is whose account the forms live in.
If they all live in yours, you have quietly become a single point of failure: when your card expires, a dozen contact forms start showing upgrade notices. Billing that as a retainer item is fine, as long as the client has been told.
Google Forms: the honest answer is no
This gets asked constantly and the truthful answer disappoints people. Google Forms branding cannot be removed. Not free, not on paid Google Workspace, not with a setting buried in a menu. Google's own support page on embedding walks you through the Embed HTML option and does not mention branding anywhere, because no control exists.
The add-ons that appear to solve it — Formfacade and TakumiForm are the two you will find — remove nothing from Google Forms. They read your form and re-render the questions on their own infrastructure, outside Google's iframe. That may be a good trade, but a second vendor now sits between your client and their enquiries. If an unbranded form is a requirement, say so at the proposal stage, not at handover.
The thing everyone gets wrong: CSS does not cross the frame
An iframe is not a region of your page. It is a second document, with its own DOM and its own stylesheets, that the browser renders inside a rectangle on yours. Nothing in your stylesheet reaches it — the most specific selector you can write will do nothing, because the cascade does not cross that boundary. And because the form is hosted on the vendor's domain, the same-origin policy closes the other door: your JavaScript cannot query into the frame, inject a style tag, or read a single element.
So every visual decision has to be made inside the form tool's own theme settings. Open the site's stylesheet, copy the real hex codes, and set the colours, radius, button style and field borders there rather than from memory.
Fonts bite hardest. A webfont loaded by the parent page does not exist inside the frame, so a form set to use it falls back silently and the seam shows. Load the same font inside the form tool if it allows that, or pick a neutral system stack and make it look deliberate. Then give the iframe width: 100%, border: 0 and display: block — iframes are inline by default, which is where the mysterious few pixels of whitespace under an embed come from.
The height problem, and the three ways out
An iframe does not grow with its contents. The browser gives it a default height of roughly 150 pixels, and whatever you set is the height it keeps. Too short and the form scrolls inside its own little window, a scrollbar within a scrollbar; too tall and there is dead space under the button.
A fixed height measured on your desktop is wrong the moment the page opens on a phone. At 390 pixels wide, labels wrap and fields stack, so the same form can be half again as tall — and conditional fields and validation messages change the height mid-session. No single number is correct.
- Use the vendor's embed script where one exists. It owns both ends of the conversation, handles resizing, and usually the scroll position after submission too.
- Write the postMessage handshake yourself, if the embedded page cooperates. The form document posts its own scrollHeight to the parent whenever it changes; the parent listens, checks event.origin against the expected host, and sets the height. About fifteen lines — and only possible if the embedded page sends the message.
- Use iframe-resizer, which does the same properly with ResizeObserver and MutationObserver. Read the licence first: it is dual-licensed, GPL v3 for open-source projects or a paid commercial licence otherwise. A client's proprietary site is not GPL-compatible, so that is a cost for the quote.
Some forms cannot be embedded at all
Before any of that matters, check the form will render in a frame on the client's domain. A server can send X-Frame-Options: DENY, which blocks framing everywhere, or SAMEORIGIN, which permits it only on the provider's own domain. The old ALLOW-FROM value is obsolete, and browsers now ignore the whole header when they meet it. It also only works as a real HTTP response header — in a meta tag it does nothing.
The modern equivalent is the Content-Security-Policy frame-ancestors directive, which supersedes X-Frame-Options and names the origins allowed to frame a page. If the client's domain is not among them the browser refuses, and the symptom is an empty rectangle with a refusal in the console. There is no workaround on your side, so test on the real domain over HTTPS — localhost can pass where production fails, because the origin differs.
The pre-handover checklist
Run this before the invoice goes out, on the live domain, on a real phone rather than a resized browser window.
- No vendor badge, logo, footer link or watermark anywhere, including the thank-you state.
- View source: the iframe src does not expose a vendor domain, or points at a custom subdomain.
- Colours, radius, button style and field borders match the site — set inside the form tool, not in your CSS.
- The font matches the site or is a deliberate neutral choice, checked inside the frame rather than assumed.
- Height adjusts as the form grows: trigger a validation error and any conditional field, and watch it.
- No inner scrollbar at 390 pixels wide, and no dead whitespace under the button at 1440.
- After submission the confirmation is visible without scrolling up inside the frame.
- It renders on the production domain over HTTPS, not only on staging.
- Submissions reach an address the client controls, and a test one has landed there.
- The client knows whose account the form lives in, what it costs, and how to get in when you are no longer around.
What this comes down to
None of these tools are behaving badly. Free tiers are paid for by the badge, and that is a fair, openly stated arrangement for somebody using the tool for themselves.
Agency work is the same situation wearing different clothes. You are not the user; the client is, and they will still be the user long after you have stopped thinking about this project. Seen that way, the question stops being how to hide a logo and becomes which tool you can hand over cleanly — unbranded, in an account somebody can get into, correctly sized on a phone, and rendering on the domain it has to render on.