Skip to content

Tagging the form

Every attribute here goes on the <form> element itself. Attributes that go on the fields are in The fields.

Required

data-nam-landing-page

The landing page id we registered for this form. It is also the routing key that decides which campaign the visitor's session resolves to, so it has to match the entry point exactly.

This is the only attribute the SDK refuses to start without. discoverForms selects on it alone, so a form without it is invisible to the SDK.

Allowed: letters, digits, ., :, _ and -; must start with a letter or digit; 100 characters at most.

data-nam-key

The publishable key for that page. It is safe in page source — it identifies the page, it does not authorise anything else, and the session token it exchanges for is held in memory and never written to storage.

The key can also be passed as init({ key }), or set on window.__NAMAKINA_LANDING_PAGE__.key. When more than one is present the attribute wins.

A rotate invalidates the previous key

If the key is rotated on our side, the page still carrying the old one gets a 401 on every session and the widget silently never appears. See Troubleshooting.

data-nam-goal

What finishing the form gets the visitor, in their own words, in one sentence. The agent uses it to keep every turn moving toward that outcome, and it is sent with every snapshot.

Get a free, no-obligation quote for protecting your home — a local specialist calls you back within a business day.

It is the visitor's outcome, not a list of fields to collect. The form already says what to collect.

Capped at 500 characters.

Optional, but only technically

The SDK starts without it. The conversation is materially worse without it, because the agent has nothing to steer toward but the field list.

Optional

AttributeValuesDefaultWhat it does
data-nam-goal-labelA few wordsThe submit button's own text, sentence-cased; Finish if there is noneThe label on the progress strip, e.g. Your free quote. Also the panel title when data-nam-brand is absent.
data-nam-contextFree text, capped 300noneBackground the agent should know that is not on the page. Also valid on an individual field.
data-nam-rollout0100; anything else is clamped and rounded100The share of visitors who get the agent. See Rollout and holdout.
data-nam-submitconfirm, autoconfirmconfirm waits for the visitor to press your own button. auto submits as soon as the agent asks to. See Submit.
data-nam-layoutinline, panelinlineWhere the conversation renders. See Layouts.
data-nam-brandA namefalls back to the goal labelThe panel header's title; its first letter becomes the round mark beside it.
data-nam-themeA JSON object of CSS custom propertiesnoneOverrides the colours and fonts sampled from your page. See Theming.

A worked example

html
<form
  action="/estimate"
  method="post"
  id="EstimateForm"
  novalidate
  data-nam-landing-page="kestrel"
  data-nam-key="lp_live_xxxxxxxx"
  data-nam-rollout="50"
  data-nam-goal="A no-obligation estimate of what solar would save you, with no site visit."
  data-nam-goal-label="Your free estimate"
  data-nam-brand="Kestrel"
  data-nam-layout="panel"
  data-nam-theme='{"--nam-accent":"#e8862b","--nam-image-position":"center 30%"}'
>

Quote the theme carefully

data-nam-theme holds JSON, which uses double quotes, so the attribute has to be wrapped in single quotes. If the JSON itself contains a single quote, escape it as &#39; — an unescaped one truncates the attribute at that character and the browser scatters the rest as bare attributes. The SDK parses what it is given, silently returns null for anything malformed, and falls back to the sampled colours, so this failure looks like "the theme just did not apply".

Two forms on one page

Each tagged form gets its own controller and its own conversation. They can carry different ids and different keys. Fields are never shared between them.

Forms that appear later

init() installs a MutationObserver and rescans about 250 ms after the DOM settles, so a form added by a single-page app is picked up on its own. If you have a case the observer cannot see, call scan() yourself — it starts controllers for tagged forms that do not have one and evicts controllers whose form has left the DOM.

Proprietary. All rights reserved.