Create a form in Kajabi with a unique Timeline form field. Do NOT make this new form field mandatory. Add an automation to start an email sequence. Select this form in the sidebar. Save the page to run the field finder script.
YOUR FORM FIELD FINDER SETTINGS:
Kajabi Form selected: De GroenteShift 90 dagen - Timeline Funnel
No custom form fields are found. You might need to refresh this page to run the search script.
Step 2: Timeline Funnel Settings
Copy the Timeline form field ID from step 1 to the sidebar. A cookie is needed to add extra security to your funnel. You can deselect the cookie option if you don't want to use a cookie or when you want to test your funnel.
Running multiple Timeline Funnels on the same site? Use a different Field ID for each funnel. Each funnel needs its own unique field to track visitors independently.
YOUR FUNNEL SETTINGS:
Timeline Form Field ID: 20
Cookie will be set for 50 days
Step 3: Funnel Starting Trigger
Kick off your funnel with an opt-in form on a landing page or via a Zapier trigger.
START WITH A ZAPIER TRIGGER
Start the funnel when a Zapier action is triggered. Copy the code to add it to your Zap. Follow the video tutorial.
Select the duration of the countdown timer, calculated from the moment the trigger became active. Optionally, configure what happens when the timer expires — for example, redirect visitors to a page without the special offer.
Style the countdown timer layout. The changes can be seen in the timer on top of this page.
Optional: You can change this width of the countdown timer in the settings to match the block size on your landing page.
Step 6: Special Offer Landing Page
The countdown code is split into two parts.
Part 1 – Top of page (redirect guard): Paste this once into a Custom Code block at the very top of your landing page. It runs before any content is rendered and immediately redirects expired visitors. Contains no visible HTML.
Part 2 – Timer display: Paste this wherever you want the countdown timer to appear. Can be placed multiple times on the same page for multiple timers. Requires Part 1 to be present on the same page.
Optional: You can also add both parts to the thank-you page after the first opt-in to show the timer immediately.
YOUR LANDING PAGE COUNTDOWN TIMER SETTING:
Default setting: Timeline code is shown in the url
<script>
(function() {
var isAdmin = window.location.href.includes('app.kajabi.com/admin/themes/') ||
new URLSearchParams(window.location.search).has('preview_theme_id');
if (!isAdmin) document.body.style.display = 'none';
})();
function isInTestMode() {
const url = window.location.href;
const isKajabiAdmin = url.includes('app.kajabi.com/admin/themes/');
const previewParam = getQueryParam('preview_theme_id');
return isKajabiAdmin || previewParam;
}
function getQueryParam(name) {
const params = new URLSearchParams(window.location.search);
return params.get(name);
}
function setCookie(name, value, days) {
let expires = "";
if (days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function deleteCookie(name) {
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
}
function getCookie(name) {
const nameEQ = name + "=";
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i].trim();
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function hideQuery() {
if (!isInTestMode()) {
var url = window.location.href;
var newUrl = url.split('?')[0];
history.replaceState({}, document.title, newUrl);
}
}
const settings = {
setcookie: true,
setcookienumber: "20",
setcookiedays: 50,
tltimeendday: false,
tltimeday: 0,
tltimehour: 48,
tltimemin: 0,
tlenable_end_action: "redirect",
tlaction: "https://www.sarahdeboercoaching.eu/DeGroenteShift90dagenEenmalig",
useFlipAnimation: false,
tlredirect_delay: false,
tlredirect_delay_seconds: 5,
tlredirect_delay_message: "This offer has expired. Redirecting in X seconds...",
tlenable_expired_message: true,
tlexpired_message: "This offer has ended."
};
window.TL = window.TL || {};
window.TL.settings = settings;
function isValidTParameter(t) {
const regex = new RegExp('^\\{\\{.*\\}\\}$');
return !regex.test(t);
}
function resterendeTijdTotEindeVanDag(tijdstempel) {
var eindeVanDag = new Date(tijdstempel);
eindeVanDag.setHours(23, 59, 59, 999);
return eindeVanDag.getTime() - tijdstempel;
}
function handleEndAction() {
if (!isInTestMode() && settings.tlenable_end_action === "redirect") {
if (settings.tlredirect_delay) {
document.body.style.display = '';
function showRedirectMessage() {
var delaySecs = settings.tlredirect_delay_seconds || 5;
var msgEl = document.createElement('div');
msgEl.className = 'tl-redirect-message';
msgEl.innerText = (settings.tlredirect_delay_message || 'Redirecting in {n} seconds...').replace('{n}', delaySecs);
msgEl.style.cssText = 'position:fixed;inset:0;z-index:99999;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,0.95);font-size:24px;font-weight:bold;color:#333;text-align:center;padding:40px;';
document.body.appendChild(msgEl);
var countdownInt = setInterval(function() {
delaySecs--;
if (delaySecs <= 0) {
clearInterval(countdownInt);
window.location.replace(settings.tlaction);
} else {
msgEl.innerText = (settings.tlredirect_delay_message || 'Redirecting in {n} seconds...').replace('{n}', delaySecs);
}
}, 1000);
}
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', showRedirectMessage);
} else {
showRedirectMessage();
}
} else {
window.location.replace(settings.tlaction);
}
} else if (settings.tlenable_end_action === "none" && settings.tlenable_expired_message) {
document.body.style.display = '';
function showExpiredMessage() {
var expiredEl = document.createElement('div');
expiredEl.className = 'tl-expired-message';
expiredEl.innerText = settings.tlexpired_message || 'This offer has ended.';
expiredEl.style.cssText = 'position:fixed;inset:0;z-index:99999;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,0.95);font-size:24px;font-weight:bold;color:#333;text-align:center;padding:40px;';
document.body.appendChild(expiredEl);
}
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', showExpiredMessage);
} else {
showExpiredMessage();
}
} else {
document.body.style.display = '';
}
}
function process(encodedData) {
if (isInTestMode()) {
if (window.TL.endTime && new Date().getTime() < window.TL.endTime) {
window.TL.settings = settings;
document.body.style.display = '';
return;
}
const now = new Date().getTime();
const offset = (settings.tltimeday * 86400000) + (settings.tltimehour * 3600000) + (settings.tltimemin * 60000);
const endOfDay = settings.tltimeendday ? resterendeTijdTotEindeVanDag(now) : 0;
const endTime = now + offset + endOfDay;
window.TL.endTime = endTime;
document.body.style.display = '';
document.dispatchEvent(new CustomEvent('tl:ready', { detail: { endTime: endTime } }));
(function() {
var guardTimer = setInterval(function() {
if (new Date().getTime() >= endTime) {
clearInterval(guardTimer);
handleEndAction();
}
}, 1000);
})();
return;
}
if (!encodedData) return handleEndAction();
const tlcdt = encodedData.toString().split("").reverse().join("");
const tlcsomEnd = tlcdt.indexOf("dC");
const tlcsom = parseInt(tlcdt.substring(2, tlcsomEnd), 10);
const tlctmEnd = tlcdt.indexOf("Gt");
const tlctm = tlcdt.substring(tlcsomEnd + 6, tlctmEnd);
const tlctmInt = parseInt(tlctm);
const tlcalsom = [...tlctm].reduce((sum, n) => sum + parseInt(n, 10), 0);
const tlgrt = tlcdt.match(/Hrf(.+?)fU/)?.[1];
const tlgrtl = tlctm.length;
if (tlcdt.includes("R1969") && tlcdt.includes("dC3729") && tlcalsom == tlcsom && tlgrt == tlgrtl) {
const now = new Date().getTime();
const offset = (settings.tltimeday * 86400000) + (settings.tltimehour * 3600000) + (settings.tltimemin * 60000);
const endOfDay = settings.tltimeendday ? resterendeTijdTotEindeVanDag(tlctmInt) : 0;
const endTime = tlctmInt + offset + endOfDay;
if (endTime > now) {
window.TL.endTime = endTime;
document.body.style.display = '';
document.dispatchEvent(new CustomEvent('tl:ready', { detail: { endTime: endTime } }));
(function() {
var guardTimer = setInterval(function() {
if (new Date().getTime() >= endTime) {
clearInterval(guardTimer);
handleEndAction();
}
}, 1000);
})();
} else {
handleEndAction();
}
} else {
handleEndAction();
}
}
function startTimer() {
try {
const encodedData = getQueryParam('t');
if (settings.setcookie) {
if (encodedData && isValidTParameter(encodedData)) {
setCookie(`timeline${settings.setcookienumber}`, encodedData, settings.setcookiedays);
}
} else {
deleteCookie(`timeline${settings.setcookienumber}`);
}
const cookieData = getCookie(`timeline${settings.setcookienumber}`);
process(encodedData || cookieData);
} catch (err) {
console.error("Timeline Funnel error:", err);
document.body.style.display = '';
}
}
startTimer();
</script>
Paste the address of your special offer page from step 6 into the settings. This generates a personalised link you can use in your Kajabi email sequences — when a subscriber clicks it, their countdown timer starts.
Optional: If you use a third-party email tool like ActiveCampaign, forward the timeline field to that tool and replace the placeholder with its merge tag.
The code ?t={{custom_20}} must be added to the end of the page url to personalize the link.
Before going live, test your funnel to verify your funnel works correctly.
Use the test links below and open them in a different browser than your Kajabi admin account.
The opt-in page test URL has ?jiffytestmode appended — this clears cookies and resets the timer on every page load.
The special offer page test URL uses a freshly generated scrambled code, so it will always show the offer regardless of previous cookies.
Do not use these URLs in your live funnel.
YOUR OPT-IN PAGE TEST URL (UPDATE URL IN STEP 3):
Your funnel is set to start via Zapier. Switch to "Opt-in page" in Step 3 if you want to use this test link.
YOUR SPECIAL OFFER PAGE TEST URL (UPDATE URL IN STEP 7):