Sign in
← Jotform
Jotform · Install guide

Source Code embed

The Source Code embed gives you the form's raw HTML to paste into your page. No iframe, no cross-origin boundary — the fields are real inputs in your own DOM, which the tag fills the same way it fills any hand-built form. This is the simplest of the three routes and the only one with no URL-length ceiling. Two things to know: it's offered for Classic forms only, and the HTML you paste is a snapshot — edit the form later and you have to re-copy it.

1

Put a token in each hidden field's Default Value

Jotform names every input after its question — q21_…, q22_…— and you can't change that prefix, so matching by nameis out. Populate by token instead: in the form builder, open each hidden field's Properties panel and set its Default Value to the [mtk:…] token for the value you want, e.g. [mtk:first.source]. The tag replaces the token with the resolved value on load, when new content is injected, and again at submit.

Add one field per value, and leave Hide Field on for all of them. Save the form.

Where the tokens come from:Dashboard → the client's license → Tag config → Field map → the Token column, with a copy button on every row.
2

Copy the source code and paste it into your page

Go to Publish → Embed, choose Source Code from the list, and click Copy Code. Paste the whole thing — markup, styles and scripts — into your page where the form should appear. Nothing in it needs editing.

Keep the block intact. Jotform's own scripts in that code handle validation and posting the submission back to Jotform, so a partial paste gives you a form that renders but never submits.

3

Publish and verify

Publish, then load the page in a private window with a test URL like ?utm_source=googleads&utm_medium=cpc, submit the form, and check the entry under Submissions in Jotform.

To check it without submitting, run this in the console on the page with the form:

console.log([...document.querySelectorAll('input[name*="mtk_"]')]
  .map(function (i) { return i.name + ' = ' + i.value; })
  .join('\n'));

Every field the visit has a value for should show it. Ones it doesn't — content, referrer, a click ID from a network the test visit didn't come from — are correctly empty, so a handful of blanks on a direct test visit is normal. What is not normal: a field still showing its [mtk:…] token, or every field empty at once. The list below covers both.

If the fields come back wrong, work down this list — each step rules out one layer:

1. The submission contains the literal [mtk:…] text.The tag never replaced the tokens, and the usual reason is that the form isn't actually in your page. View the page source: a Source Code paste puts <form class="jotform-form" in your own HTML. If you find a <script src="…/jsform/…"> or an <iframe>instead, the page is on the Standard or iFrame route — the tokens are sitting inside Jotform's frame where nothing replaces them, and Jotform submits them as typed. Re-paste the Source Code, or clear the Default Values and follow that route's guide. Tokens and the iframe routes never mix.

2. Every field is empty, and the inputs in the pasted HTML read value="".The tokens weren't in the Default Values when you copied the source — set them, save, and copy the code again. The paste is a snapshot; it doesn't pick up builder changes made after it.

3. Every field is empty, but the tokens are in the HTML. Only the submit-time capture is failing. Check the console for errors from Jotform's own scripts — a partial paste that dropped them renders the form but never posts it.

4. Is the tag itself loading? No mtk_attribution event in window.dataLayermeans it was blocked, usually by an ad blocker. Tokens stay in place when the tag doesn't run, so a blocked visitor's entry shows the token text — that is the tag's absence, not a form problem.

Still stuck? Troubleshooting.
Re-copy the source after every form edit. This is the one real cost of the route. The pasted HTML is a point-in-time snapshot: add a field, rename a question, or change validation in the builder and your page keeps serving the old markup — with no warning, because the old form still submits perfectly happily. Anyone editing these forms needs to know that. If the form changes often, the iFrame embed stays current on its own.
Unique Names aren't used on this route.They matter for the two iframe routes, where they're the query parameter Jotform prefills from. Here the token does the work, so a field with no Unique Name set fills perfectly well. Setting them anyway costs nothing and makes the form portable if you switch embed methods later.
No URL, no ceiling. Values go straight into the inputs, so nothing competes for space in a query string — this is the only route that captures Journey JSON and Attribution Summaryin full. If a long value is the reason you're here, this is the route that carries it.
Don't see Source Code under Publish → Embed? The form is a Card form — the option is Classic-only. Convert it to Classic in the builder, or use the Standard or iFrame route instead.