Configurare Landinguri
- Crearea paginilor HTML în GC cu AI
- Prompturi Utile
- Netlify – Publicarea Landingurilor
- Structura unui Widget
- Configurarea obligatorie a widgeturilor pentru Meta Ads (Facebook)
- Widgeturile de înscriere — structură și blocuri de acțiuni
- Redirect spre pagina de mulțumire pentru ofertele cu plată
Crearea paginilor HTML în GC cu AI
1. Ghidul „HTML în 15 minute”
Acest document prezintă procesul complet de creare a unei pagini HTML:
- pregătirea informațiilor;
- utilizarea promptului;
- generarea codului HTML cu AI;
- inserarea codului în GetCourse;
- configurarea formularului;
- publicarea paginii.
În plus, documentul conține:
- exemple de structură pentru pagini;
- stiluri CSS gata de utilizare;
- mai multe teme vizuale (Modern, Dark, Luxury etc.);
- recomandări pentru personalizarea formularelor.
2. Workshop-ul „Cum să creezi pagini în GetCourse în 15 minute cu AI”
Prezentarea explică metodologia utilizată pentru generarea paginilor și bunele practici.
Sunt abordate următoarele subiecte:
- principiile Vibe Coding;
- utilizarea AI pentru generarea codului HTML;
- pregătirea structurii proiectului;
- realizarea prompturilor eficiente;
- modificarea paginilor prin iterații scurte;
- integrarea paginilor în GetCourse.
De asemenea, sunt prezentate exemple practice și demonstrații complete.
Skill-ul pentru widgeturile GetCourse (getcourse-form-css)
Pe lângă ghidurile pentru generarea paginilor HTML, pachetul include și Skill-ul getcourse-form-css, destinat utilizării în Claude.
Acest Skill extinde capabilitățile modelului și îl specializează pentru stilizarea widgeturilor și formularelor din GetCourse.
În loc să explici de fiecare dată cum funcționează widgeturile platformei, Skill-ul oferă deja aceste informații, iar Claude poate genera direct cod CSS compatibil.
Prompturi Utile
PROMPT 1 — Widget GetCourse Modal + Rutarea Butoanelor
Am un landing page HTML de webinar (fișierul e în proiect).
Adaugă modalul GetCourse și rutarea butoanelor fără să modifici designul.
─── CSS (adaugă la sfârșitul blocului <style> existent) ───
.gc-overlay{position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.6);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:opacity 0.3s ease,visibility 0.3s ease}
.gc-overlay.active{opacity:1;visibility:visible}
.gc-modal{position:relative;background:#fff;border-radius:16px;width:94%;max-width:520px;max-height:90vh;overflow:hidden;transform:translateY(24px) scale(0.97);transition:transform 0.3s ease;box-shadow:0 24px 80px rgba(0,0,0,0.25)}
.gc-overlay.active .gc-modal{transform:translateY(0) scale(1)}
.gc-modal__close{position:absolute;top:12px;right:12px;z-index:2;width:36px;height:36px;border-radius:50%;border:none;background:rgba(0,0,0,0.06);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background 0.2s}
.gc-modal__close:hover{background:rgba(0,0,0,0.12)}
.gc-modal__close svg{width:18px;height:18px;stroke:#333;stroke-width:2.5}
.gc-modal__body{overflow-y:auto;max-height:90vh;-webkit-overflow-scrolling:touch}
.gc-modal__body iframe{display:block;width:100%;min-height:550px;border:none}
─── HTML modal (adaugă imediat înainte de </body>) ───
<div class="gc-overlay" id="gc-overlay" onclick="if(event.target===this)closeGcModal()">
<div class="gc-modal">
<button class="gc-modal__close" onclick="closeGcModal()" aria-label="Închide">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
<div class="gc-modal__body">
<iframe id="gc-iframe" src="" allow="payment"></iframe>
</div>
</div>
</div>
─── Script widget (adaugă după HTML modal) ───
<script>
(function(){
var BASE_URL = 'https://edu.inginer.ai';
var WIDGETS = { standard: '1610817', vip: '1610799' };
var STORE_KEY = '__inginer_utms';
var KEYS = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content'];
function readFromUrl(){
var out = {};
var sp = new URLSearchParams(window.location.search);
KEYS.forEach(function(k){ var v=sp.get(k); if(v) out[k]=v; });
var hash = window.location.hash;
var qi = hash.indexOf('?');
if(qi !== -1){
var hsp = new URLSearchParams(hash.slice(qi+1));
KEYS.forEach(function(k){ var v=hsp.get(k); if(v) out[k]=v; });
}
return out;
}
function load(){ try{ var s=sessionStorage.getItem(STORE_KEY); return s?JSON.parse(s):{}; }catch(e){ return {}; } }
function save(o){ try{ sessionStorage.setItem(STORE_KEY,JSON.stringify(o)); }catch(e){} }
var merged = Object.assign({}, load(), readFromUrl());
if(Object.keys(merged).length) save(merged);
window.__getUtms = function(){ return Object.assign({}, load(), readFromUrl()); };
function buildWidgetUrl(widgetId){
var utms = window.__getUtms();
var params = new URLSearchParams(Object.assign({ id: widgetId, ref: window.location.href, loc: window.location.href, clrtQueryData: '1' }, utms));
return BASE_URL + '/pl/lite/widget/widget?' + params.toString();
}
window.openGcModal = function(type){
var overlay = document.getElementById('gc-overlay');
var iframe = document.getElementById('gc-iframe');
if(!overlay || !iframe) return;
iframe.src = buildWidgetUrl(WIDGETS[type]);
overlay.classList.add('active');
document.body.style.overflow = 'hidden';
};
window.closeGcModal = function(){
var overlay = document.getElementById('gc-overlay');
var iframe = document.getElementById('gc-iframe');
if(!overlay) return;
overlay.classList.remove('active');
document.body.style.overflow = '';
setTimeout(function(){ if(iframe) iframe.src = ''; }, 300);
};
document.addEventListener('keydown', function(e){ if(e.key==='Escape') closeGcModal(); });
window.addEventListener('message', function(event){
if(!event.origin.includes('edu.inginer.ai')) return;
if(event.data && typeof event.data==='object' && event.data.type==='resize'){
var iframe = document.getElementById('gc-iframe');
if(iframe && event.data.height > 0) iframe.style.height = event.data.height + 'px';
}
});
})();
</script>
─── Rutarea butoanelor ───
Caută toate <button> și <a class="btn"> din fișier și aplică regula:
- Butoane DIN AFARA secțiunii de prețuri:
onclick="document.getElementById('pricing').scrollIntoView({behavior:'smooth'})"
(dacă secțiunea de prețuri nu are id="pricing", adaugă-l pe elementul părinte)
- Butonul Standard DIN secțiunea de prețuri:
onclick="openGcModal('standard')"
- Butonul VIP DIN secțiunea de prețuri:
onclick="openGcModal('vip')"
PROMPT 2 — Script dată automată + Countdown
Am un landing page HTML de webinar (fișierul e în proiect).
Adaugă scriptul de dată automată și countdown fără să modifici designul.
Reguli:
- Webinarul are loc în fiecare MARȚI la ora 19:00 (ora României), reluarea MIERCURI la 19:00
- Data se calculează dinamic la fiecare vizită — niciodată hardcodată
- Dacă azi e marți dar ora 19:00 a trecut, sare la marțea următoare
Caută în fișier elementele de mai jos și populează-le. Dacă un element nu există, sari peste el.
| ID / selector | Ce afișează |
|---------------------|----------------------------------------------------------|
| #hero-live-date | ex: „Marți, 24 iunie", ora 19:00 (ora României) |
| #hero-reluare-date | ex: „Reluare: Miercuri, 25 iunie · 19:00" |
| #live-date | varianta scurtă cu emoji 📅 și dată bold |
| #reluare-date | varianta scurtă cu emoji 📅 și dată bold |
| #micro-live | linie compactă: dată · 19:00 · 90 minute · sesiune live |
| #final-cta-date | dată bold în secțiunea finală de CTA |
| .eyebrow.live | text uppercase: LIVE · DOAR 150 LOCURI · DATA · 19:00 |
| cd-d sau cd-days | countdown zile (detectează automat ce prefix există) |
| cd-h sau cd-hours | countdown ore |
| cd-m sau cd-minutes | countdown minute |
| cd-s sau cd-seconds | countdown secunde |
Scriptul de adăugat (adaptează ID-urile countdown la ce există în fișier):
<script>
(function(){
var MONTHS_RO = ['ianuarie','februarie','martie','aprilie','mai','iunie','iulie','august','septembrie','octombrie','noiembrie','decembrie'];
var DAYS_RO = ['Duminică','Luni','Marți','Miercuri','Joi','Vineri','Sâmbătă'];
function getNextTuesday() {
var now = new Date();
var next = new Date(now);
next.setHours(19, 0, 0, 0);
var day = now.getDay();
var daysUntil = (2 - day + 7) % 7;
if (daysUntil === 0 && now >= next) daysUntil = 7;
next.setDate(next.getDate() + daysUntil);
return next;
}
function getNextWednesdayAfter(d) {
var r = new Date(d);
r.setDate(r.getDate() + 1);
return r;
}
var liveDate = getNextTuesday();
var reluareDate = getNextWednesdayAfter(liveDate);
function fmtShort(d) { return DAYS_RO[d.getDay()] + ', ' + d.getDate() + ' ' + MONTHS_RO[d.getMonth()]; }
function fmtUpper(d) { return DAYS_RO[d.getDay()].toUpperCase() + ', ' + d.getDate() + ' ' + MONTHS_RO[d.getMonth()].toUpperCase(); }
var eyebrowEl = document.querySelector('.eyebrow.live');
if (eyebrowEl) eyebrowEl.textContent = 'LIVE · DOAR 150 LOCURI · ' + fmtUpper(liveDate) + ' · 19:00 (ora României)';
var heroLiveEl = document.getElementById('hero-live-date');
if (heroLiveEl) heroLiveEl.innerHTML = '<strong>' + fmtShort(liveDate) + '</strong>, ora 19:00 (ora României)';
var heroReluareEl = document.getElementById('hero-reluare-date');
if (heroReluareEl) heroReluareEl.innerHTML = '<strong>Reluare</strong>: ' + fmtShort(reluareDate) + ' · 19:00';
var microEl = document.getElementById('micro-live');
if (microEl) microEl.textContent = fmtShort(liveDate) + ' · 19:00 (ora României) · 90 minute · sesiune live';
var liveDateEl = document.getElementById('live-date');
if (liveDateEl) liveDateEl.innerHTML = '📅 <strong>' + fmtShort(liveDate) + '</strong> · 19:00';
var reluareDateEl = document.getElementById('reluare-date');
if (reluareDateEl) reluareDateEl.innerHTML = '📅 <strong>' + fmtShort(reluareDate) + '</strong> · 19:00';
var finalCtaEl = document.getElementById('final-cta-date');
if (finalCtaEl) finalCtaEl.innerHTML = '<strong>' + fmtShort(liveDate) + '</strong>, ora 19:00';
var target = liveDate.getTime();
var elD = document.getElementById('cd-d') || document.getElementById('cd-days');
var elH = document.getElementById('cd-h') || document.getElementById('cd-hours');
var elM = document.getElementById('cd-m') || document.getElementById('cd-minutes');
var elS = document.getElementById('cd-s') || document.getElementById('cd-seconds');
function pad(n) { return String(Math.max(0, n)).padStart(2, '0'); }
function tick() {
var diff = target - Date.now();
if (diff <= 0) diff = 0;
var s = Math.floor(diff / 1000);
var d = Math.floor(s / 86400); s -= d * 86400;
var h = Math.floor(s / 3600); s -= h * 3600;
var m = Math.floor(s / 60); s -= m * 60;
if (elD) elD.textContent = pad(d);
if (elH) elH.textContent = pad(h);
if (elM) elM.textContent = pad(m);
if (elS) elS.textContent = pad(s);
}
tick();
setInterval(tick, 1000);
})();
</script>
Netlify – Publicarea Landingurilor
Acest articol oferă o prezentare generală a publicării unui landing page pe Netlify și pașii obligatorii folosiți în proiectele noastre.
Pașii obligatorii la publicare
1. Selectarea proiectului
Intri în contul Netlify și alegi site-ul dorit din listă (proiectul pe care vrem să-l actualizăm sau publicăm).
2. Dacă site-ul e gol / nefolosit
Intri pe site → secțiunea Project overview → tragi (drag and drop) fișierul HTML dau folderul cu fişiere direct acolo. Pagina e publicată automat.
3. Dacă pe site rulează deja o pagină
- Intri pe site → Deploys;
- Descarci deployul curent;
- Adaugi pagina nouǎ în directoriul descǎrcat sau modifici cea existentǎ dacǎ e necesar;
- Tragi (drag and drop) fișierul nou în zona de Project overview;
Pagina veche este înlocuită cu cea nouă, pe același domeniu/subdomeniu, fără a schimba link-ul.
4. Revenire la o versiune anterioară
Dacă ceva nu merge bine, din Deploys selectezi un deploy mai vechi din istoric și apeși „Publish deploy” pentru a reveni la el.
Structura unui Widget
Configurarea obligatorie a widgeturilor pentru Meta Ads (Facebook)
Scop
Orice landing page care urmează să fie promovat prin Meta Ads (Facebook / Instagram) trebuie configurat astfel încât să transmită corect datele către Facebook Conversions API (CAPI).
Înainte de publicarea landing-ului, trebuie adăugate trei componente obligatorii în widget-ul formularului.
Componente obligatorii
În formular trebuie să existe următoarele elemente:
- Câmp utilizator –
fbclid - Bloc HTML (codul va fi furnizat separat)
- Procesul CAPI Facebook corespunzător proiectului
1. Adăugarea câmpului fbclid
În lista componentelor formularului se adaugă un nou câmp utilizator.
După adăugare, configurați câmpul astfel:
- Câmp:
fbclid - Titlul câmpului:
fbclid - clasa CSS trebuie să conțină:
fbclidhidden
Câmpul trebuie să fie unul ascuns (hidden), utilizatorul nu trebuie să îl vadă în formular.
2. Adăugarea blocului HTML
În formular se adaugă un widget de tip HTML.
Acesta trebuie poziționat înaintea butonului de trimitere.
În interiorul lui se introduce următorul cod:
<script>
(function () {
var KEY = 'fm_fbclid';
var TTL = 90 * 86400000;
var sp = new URLSearchParams(location.search || '');
// Сначала ищем fbclid напрямую
var fbclid = sp.get('fbclid');
// Если нет — ищем внутри ref или loc
if (!fbclid) {
var ref = sp.get('ref') || sp.get('loc') || '';
if (ref) {
var m = ref.match(/fbclid=([^&]+)/);
if (m) fbclid = m[1];
}
}
if (fbclid) {
try { localStorage.setItem(KEY, JSON.stringify({ ts: Date.now(), v: fbclid })); } catch(e) {}
}
function getStored() {
try {
var raw = localStorage.getItem(KEY);
if (!raw) return null;
var o = JSON.parse(raw);
if (!o || !o.ts || Date.now() - o.ts > TTL) return null;
return o.v || null;
} catch(e) { return null; }
}
function fill() {
var val = fbclid || getStored();
if (!val) return;
document.querySelectorAll('.fbclid input, .fbclid textarea').forEach(function(el) {
if (!el.value) { el.value = val; }
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', fill);
} else { fill(); }
setTimeout(fill, 500);
setTimeout(fill, 1500);
})();
</script>
3. Adăugarea procesului CAPI Facebook
Din secțiunea Gestionarea formularului se adaugă acțiunea Lansare proces.
În funcție de proiectul pentru care se realizează campania, se selectează unul dintre următoarele procese:
| Proiect | Proces |
|---|---|
| Manifestare | CAPI Facebook |
| Banii la Treabă | CAPI Facebook |
| Inginer | CAPI Facebook Inginer |
| VibeCoding | CAPI Facebook Vibe Coding |
Se recomandă păstrarea bifată opțiunea:
- Executați din nou dacă sarcina pentru acest utilizator a fost deja lansată
Verificare înainte de publicare
Înainte ca landing page-ul să intre în publicitate, verificați că sunt îndeplinite toate condițiile:
- ✅ există câmpul utilizator fbclid
- ✅ câmpul are clasele CSS fbclid și hidden
- ✅ este adăugat blocul HTML
- ✅ este introdus codul HTML necesar
- ✅ este configurat procesul CAPI Facebook corespunzător proiectului
- ✅ formularul este salvat și publicat
Exemple de widget-uri configurate
Mai jos sunt câteva exemple de widget-uri care au fost configurate corect și sunt utilizate în producție.
Exemplul 1 – Manifestare
Exemplul 2 – Banii la Treabă
Exemplul 3 – Inginer
Exemplul 4 – Vibe Coding
Widgeturile de înscriere — structură și blocuri de acțiuni
Widgetul este formularul de înscriere de pe landing. Pe lângă câmpurile vizibile, el conține o listă de acțiuni care se execută în ordine, la trimiterea formularului. Articolul descrie ce conține fiecare variantă de widget — Gratuit și VIP — și ce face fiecare bloc.
Widgetul Gratuit
Blocurile, în ordinea în care apar și se execută:
| # | Bloc | Ce face |
|---|---|---|
| 1 | Autorizați utilizatorul | Autentifică automat utilizatorul în cont, ca să nu fie nevoit să se logheze manual |
| 2 | Lansare proces | Pornește procesul descris în articolul Configurarea obligatorie a widgeturilor pentru Meta Ads (Facebook) |
| 3 | Creare cerere / comandă | Creează comanda pe oferta corespunzătoare |
| 4 | Trimite o scrisoare | Trimite emailul de confirmare |
| 5 | Configurați comanda | Se adaugă eticheta, în caz de necesitate |
| 6 | Redirecționare | Trimite utilizatorul pe pagina de mulțumire |
Ce se întâmplă imediat după trimiterea formularului
- Redirect spre pagina de mulțumire — imediat după completarea și trimiterea formularului, fără pas intermediar de plată.
- Expedierea emailului — tot imediat după trimiterea formularului, nu la un interval ulterior.
Restul acțiunilor (creare comandă, configurare, lansare proces) rulează în fundal, în același moment.
Widgetul VIP
Blocurile, în ordinea în care apar și se execută:
| # | Bloc | Ce face |
|---|---|---|
| 1 | Autorizați utilizatorul | Autentifică automat utilizatorul în cont |
| 2 | Lansare proces | Pornește procesul descris în articolul Configurarea obligatorie a widgeturilor pentru Meta Ads (Facebook) |
| 3 | Creare cerere / comandă | Creează comanda pe oferta VIP |
| 4 | Configurați comanda (opțional) | Poate fi prezent și aici, dacă e nevoie de adăugarea unei etichete |
Diferențele dintre Gratuit și VIP
Widgetul VIP nu conține două blocuri care există la cel gratuit:
| Bloc | Gratuit | VIP |
|---|---|---|
| Trimite o scrisoare | ✅ Da — emailul pleacă imediat după trimiterea formularului | ❌ Nu — widgetul nu expediază email |
| Redirecționare | ✅ Da — utilizatorul ajunge direct pe pagina de mulțumire | ❌ Nu — redirectul nu se face din widget |
Motivul este că oferta VIP se plătește separat. Utilizatorul nu trebuie dus pe pagina de mulțumire imediat după completarea formularului, ci abia după efectuarea plății, iar emailul de confirmare pleacă tot pe traseul de plată, nu din widget.
Redirect spre pagina de mulțumire pentru ofertele cu plată
Când o ofertă VIP se plătește, utilizatorul trebuie dus, după plată, pe pagina de mulțumire corectă. Legătura dintre ofertă și pagina de mulțumire se configurează într-un bloc de JavaScript din paginile de checkout. Fără această configurare, utilizatorul rămâne pe pagina standard după plată și nu primește instrucțiunile de acces.
Pasul 1 — Adună cele două informații necesare
Pentru fiecare ofertă nouă ai nevoie de:
a) Adresa paginii de mulțumire
Exemplu: https://manifestare.md/webinar-07_08-vip-thx
În cod se folosește doar partea de după domeniu, începând cu /:
/webinar-07_08-vip-thx
b) ID-ul ofertei
Exemplu: 8592956
Pasul 2 — Deschide pagina de checkout
Configurarea se face separat pe fiecare școală. Se editează pagina școlii în care se află oferta:
| Platformǎ | Pagina |
|---|---|
| Manifestare | manifestare.md |
| Inginer AI | edu.inginer.ai |
| Banii la Treabă | edu.baniilatreaba.ro |
Pasul 3 — Deschide blocul de JavaScript
În editorul paginii, dă click pe blocul de JavaScript.
Pasul 4 — Adaugă oferta în lista de redirecturi
În bloc există obiectul OFFER_REDIRECTS, care leagă fiecare ID de ofertă de pagina ei de mulțumire. Adaugă o linie nouă, după modelul celorlalte:
"8592956": "/webinar-07_08-vip-thx"
Cum arată obiectul după adăugare:
var OFFER_REDIRECTS = {
"8456396": "/practicum-thx",
"8499140": "/conferinta-social-media-vip-thx",
"8549826": "/practicum-thx-august",
"8592956": "/webinar-07_08-vip-thx"
// "7174043": "/welcome-intensiv"
};
Reguli de scriere
- Virgula. Fiecare linie se termină cu virgulă, în afară de ultima. Dacă adaugi oferta nouă la final, pune virgulă la sfârșitul liniei care era ultima înainte.
- Ghilimelele. Atât ID-ul, cât și calea se scriu între ghilimele drepte (
"). Ghilimelele „curbate", copiate din Word sau din chat, strică blocul. - Calea. Se scrie relativ, începând cu
/, fărăhttps://și fără domeniu. - Liniile cu
//sunt comentarii — redirecturi vechi, dezactivate. Se lasă așa cum sunt.
⚠️ O singură virgulă lipsă strică tot blocul, deci toate redirecturile din pagină încetează să funcționeze, nu doar cel nou adăugat.