Add voice responses to a Lighthouse Studio survey through a Free Format question. Free Format hands you the HTML of the question, which is all the widget needs — your conjoint design, your logic and your quotas are untouched.
AvailableIn the questionnaire, add a Free Format question and give it a name. That name matters more here than on any other platform: Lighthouse stores a field only when the field's name is the question's own name followed by an underscore. Add two variables to the question — an open-end text variable named <name>_text, which will hold the transcript, and a hidden variable named <name>_sid, which will hold the respondent key. Then paste the HTML block into the question's HTML editor. The block assumes the question is called V1; if you called it something else, change the two names in the HTML and the FF constant in the next step to match.
<!-- Voice Capture - paste into the Free Format question's HTML -->
<div id="gv-host"></div>
<textarea name="V1_text" id="V1_text" rows="4" cols="60"></textarea>
<input type="hidden" name="V1_sid" id="V1_sid" value="">In the same editor, paste the script block below the markup. It finds the text field by name, mounts the microphone above it and collapses Lighthouse's own box, so the respondent sees one control rather than two. Free Format HTML may not contain html, body or form tags — Lighthouse writes those itself — but a script tag is allowed, which is the reason this integration exists at all. Set FF to the exact question name and leave the rest as it is.
<script>
(function () {
var PROJECT_KEY = 'proj_XXXXXXXX';
var FF = 'V1'; // EXACT name of this Free Format question
var RESPONDENT_ID = ''; // optional: your own respondent-number merge code
var TEXT = FF + '_text'; // open-end variable that stores the transcript
var SID = FF + '_sid'; // hidden variable that stores the respondent key
// One key per respondent, not per page: Lighthouse turns pages with a full
// form POST, so anything held in a page-level variable is gone by the next
// voice question.
function respondentKey() {
if (RESPONDENT_ID) return RESPONDENT_ID;
var fresh = 'lh_' + Date.now() + '_' + Math.random().toString(36).slice(2, 10);
try {
var stored = window.sessionStorage.getItem('gv_sid');
if (stored) return stored;
window.sessionStorage.setItem('gv_sid', fresh);
} catch (e) { /* private mode: fall back to a per-page key */ }
return fresh;
}
function mount() {
var field = document.getElementById(TEXT);
var host = document.getElementById('gv-host');
if (!field || !host || host.getAttribute('data-gv-done')) return;
host.setAttribute('data-gv-done', '1');
var sessionId = respondentKey();
var sf = document.getElementById(SID);
if (sf) sf.value = sessionId;
host.setAttribute('data-project', PROJECT_KEY);
host.setAttribute('data-target', '#' + TEXT);
host.setAttribute('data-session', sessionId);
host.setAttribute('data-question', FF);
host.setAttribute('data-lang', 'es');
var s = document.createElement('script');
s.src = 'https://api.voicecapture.ai/voice.js';
s.onload = function () {
if (window.GeniusVoice && GeniusVoice.init) GeniusVoice.init(host);
};
document.body.appendChild(s);
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount);
else mount();
})();
</script>Every open-end variable in Lighthouse has a maximum length, and Lighthouse truncates at it without warning. A spoken answer to a good probe tends to run longer than the same answer typed, so set that maximum well above what you would allow for typing — a few thousand characters is a safe starting point — before you go to field. This is worth doing first because a truncated transcript looks exactly like a complete one in the export: the sentence simply stops, and nothing in the file says it was cut.
Each voice question is its own Free Format question, with its own pair of variables and its own copy of the block with FF set to that question's name. You do not have to do anything to keep them together. The respondent key is written to the browser session the first time any of them loads and read back on the ones that follow, so every recording from one respondent carries the same id even though Lighthouse turns a page between them.
Run your test on the browser link to the hosted survey. A microphone needs a secure connection and a page that is not sitting inside a frame that withholds microphone access, and the local test preview inside Lighthouse Studio does not reliably reproduce either condition. A microphone that fails to appear there tells you nothing about the real survey, and more than one setup has been rebuilt from scratch over a preview that was never going to work.
This is the step most setups skip and the one that catches the silent failure. Record fifteen seconds, wait for the upload to finish, move to the next page and finish the interview. The transcript should appear in the Voice Capture dashboard within about half a minute, and it should also be sitting in the open-end variable when you export the study data, with the respondent key in the hidden one. If the dashboard has a perfect transcript and the Sawtooth column is empty, the field name is not what Lighthouse expects — check it against the question name character by character.
Field the study as you normally would. Recordings upload and transcribe while fieldwork is running, so the open ends are readable before the study closes rather than only at the end. Export from Voice Capture to CSV on any plan, or to Excel on a paid credit pack, and join it to your Lighthouse data file on the respondent key. If the transcript is already in the open-end variable you may not need the join at all — it is there for the cases where you want the audio metadata, the language or the timing alongside the text.
Either the FF constant in the script does not match the question name, or the block was pasted somewhere other than that question's HTML editor. Open the hosted survey link with the browser console visible; the widget reports what it could not find.
Check the project key in the block first. If the key is right and you host Lighthouse on your own server rather than with Sawtooth, add that domain under Allowed domains in the project.
This is the naming convention. The input name has to be the question's own name, an underscore, then the variable name, and that variable has to exist in the question's variable list. A field Lighthouse does not recognise is dropped on submit without an error.
The open-end variable's maximum length is too short. Raise it and re-test; Lighthouse truncates silently, so nothing in the export marks where the answer was cut.
Our AI assistant can walk you through the setup step by step.
Set up Voice Capture in under 5 minutes. No credit card. No commitment.
Get Started FreeWe use cookies to improve your experience and analyze site traffic. Learn more