brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
tildaBuild and customize websites with Tilda — zero-code website builder with advanced customization. Use when someone asks to "build a website with Tilda", "Tilda Publishing", "customize Tilda site", "Tilda API", "landing page builder", "no-code website", "Tilda custom code", or "integrate Tilda with external services". Covers block-based building, custom HTML/…
Independent GitHub snapshot · Automated classification · Original documentation governs
Tilda is a block-based website builder — drag blocks onto a page, customize them visually, and publish. No backend to manage, no hosting to configure. For developers: inject custom HTML/CSS/JS into any block, use the read-only Tilda API to sync published pages to your own server, connect forms to any backend, and build custom integrations. Perfect for marketing sites, landing pages, and small e-commerce stores where non-technical staff need to update content independently.
Tilda sites are organized as:
Code for <head> (CSS, meta tags) goes into Site Settings → More → HTML code for the
head section (all pages) or Page Settings → Additional → HTML code for the head section
(one page). Code for the page body goes into a T123 "Embed HTML Code" block (Block
Library → Other) or an HTML element inside a Zero Block. The editor and the preview show
embedded code as text; it runs only on the published page.
<!-- Head section: override Tilda styles; nw-reveal is your own class on your own markup -->
<style>
.t-title { font-family: 'Inter', sans-serif !important; }
.nw-reveal { opacity: 0; transform: translateY(20px); transition: all 0.6s ease; }
.nw-reveal.is-visible { opacity: 1; transform: translateY(0); }
@media (max-width: 640px) { .t-cover__wrapper { min-height: 60vh !important; } }
</style>
<!-- T123 block: reveal .nw-reveal elements as they scroll into view -->
<script>
document.addEventListener('DOMContentLoaded', () => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) entry.target.classList.add('is-visible');
});
}, { threshold: 0.1 });
document.querySelectorAll('.nw-reveal').forEach((el) => observer.observe(el));
});
</script>
Zero Block gives you full Artboard-like control — place elements precisely with custom positioning, animations, and responsive breakpoints.
<!-- Paste into an HTML element of a Zero Block (or a T123 block) -->
<div class="custom-calculator" id="price-calc">
<h3>Price Calculator</h3>
<div class="calc-row">
<label>Number of users</label>
<input type="range" id="users" min="1" max="1000" value="10">
<span id="users-count">10</span>
</div>
<div class="calc-row">
<label>Plan</label>
<select id="plan">
<option value="starter">Starter — $5/user</option>
<option value="pro">Pro — $12/user</option>
<option value="enterprise">Enterprise — $25/user</option>
</select>
</div>
<div class="calc-result">
Total: <span id="total">$50</span>/month
</div>
</div>
<script>
const prices = { starter: 5, pro: 12, enterprise: 25 };
const usersInput = document.getElementById('users');
const planSelect = document.getElementById('plan');
function updatePrice() {
const users = parseInt(usersInput.value);
const price = prices[planSelect.value];
document.getElementById('users-count').textContent = users;
document.getElementById('total').textContent = '#x27; + (users * price).toLocaleString();
}
usersInput.addEventListener('input', updatePrice);
planSelect.addEventListener('change', updatePrice);
</script>
The API is available on the Business plan only; the keys are in Site Settings → Export → API Integration. Every request is a GET with both keys in the query string, so call it from a server, never from browser code.
// api/tilda.ts — read projects and pages from the Tilda API
const TILDA_PUBLIC_KEY = process.env.TILDA_PUBLIC_KEY;
const TILDA_SECRET_KEY = process.env.TILDA_SECRET_KEY;
const BASE_URL = "https://api.tildacdn.info/v1";
// Get all projects
async function getProjects() {
const res = await fetch(
`${BASE_URL}/getprojectslist/?publickey=${TILDA_PUBLIC_KEY}&secretkey=${TILDA_SECRET_KEY}`
);
return res.json(); // { status: "FOUND", result: [{ id, title, ... }] }
}
// Get all pages in a project
async function getPages(projectId: number) {
const res = await fetch(
`${BASE_URL}/getpageslist/?publickey=${TILDA_PUBLIC_KEY}&secretkey=${TILDA_SECRET_KEY}&projectid=${projectId}`
);
return res.json();
}
// Project settings: the export paths set in Site Settings → Export (export_imgpath,
// export_jspath, export_csspath) and the images shared by all pages
async function getProjectInfo(projectId: number) {
const res = await fetch(
`${BASE_URL}/getprojectinfo/?publickey=${TILDA_PUBLIC_KEY}&secretkey=${TILDA_SECRET_KEY}&projectid=${projectId}`
);
return (await res.json()).result;
}
// Export a page to your own hosting. getpagefullexport returns the complete HTML document
// with links rewritten to the export paths, plus the files to copy as { from, to } pairs.
// (getpagefull returns the same document with Tilda-hosted asset URLs; getpage and
// getpageexport return only the body HTML, for pasting into your own template.)
async function exportPage(pageId: number, project: any, outDir: string) {
const { mkdir, writeFile } = await import("node:fs/promises");
const res = await fetch(
`${BASE_URL}/getpagefullexport/?publickey=${TILDA_PUBLIC_KEY}&secretkey=${TILDA_SECRET_KEY}&pageid=${pageId}`
);
const page = (await res.json()).result; // { id, title, filename: "page1001.html", html, images, ... }
await writeFile(`${outDir}/${page.filename}`, page.html);
const groups = [[page.images, project.export_imgpath], [page.js, project.export_jspath], [page.css, project.export_csspath]];
for (const [files, dir] of groups) {
await mkdir(`${outDir}/${dir}`, { recursive: true });
for (const file of files ?? []) {
const body = Buffer.from(await (await fetch(file.from)).arrayBuffer());
await writeFile(`${outDir}/${dir}/${file.to}`, body);
}
}
}
Copy project.images the same way; getprojectinfo with &webconfig=htaccess (or nginx) also returns the server rules. To be told when a page is republished, set a webhook URL in the same API Integration panel: Tilda sends a GET with pageid, projectid, published and publickey, expects the body ok within 5 seconds, and retries twice.
// webhook/tilda-form.ts — Receive Tilda form submissions
/**
* Configure in Tilda: Site Settings → Forms → Webhook (the script URL must be HTTPS),
* then tick WEBHOOK in the Content panel of each form block and republish the page.
* Tilda sends a form-encoded POST on every submission and waits 5 seconds for the
* response; after a timeout it retries twice, a minute apart, so keep the handler fast.
*/
const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
const TELEGRAM_CHAT_ID = process.env.TELEGRAM_CHAT_ID;
export async function handleTildaForm(req: Request) {
const data = Object.fromEntries(await req.formData());
// data: { Name: "Kai Chen", Email: "kai@riverside.io", Phone: "+14155550142",
// tranid: "467251:8442970", formid: "form48844953" } — keys are the fields' variable names
// Save to CRM
await fetch("https://api.riverside.io/leads", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: data.Name, email: data.Email, phone: data.Phone, source: "tilda-landing",
}),
});
// Notify the sales team on Telegram
await fetch(`https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
chat_id: TELEGRAM_CHAT_ID,
text: `New lead\nName: ${data.Name}\nEmail: ${data.Email}\nPhone: ${data.Phone}`,
}),
});
return new Response("OK");
}
externalid) to receive the ordered products in a structured form.Page title, description and social preview are set per page in Page Settings (General, SEO
and Social media tabs). Google Analytics and Google Tag Manager need no code: enter the
Google tag ID (GA4) or the GTM container ID in Site Settings → Analytics (for GA4 also
tick "Enable gtag.js" in the counter's settings) and publish all pages. Tilda then reports
form submissions as virtual page views such as /tilda/form31751802/submitted, and button
clicks and pop-ups when that is switched on in the block's settings. Use one route only —
the built-in counter, GTM, or a pasted snippet — or visits are counted twice. Any other
tag, or the snippet below with your own Measurement ID, goes into Site Settings → More →
HTML code for the head section.
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7PK2D9QLMS"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-7PK2D9QLMS');
</script>
User prompt: "Create a landing page for a SaaS product with hero, features, pricing, FAQ, and contact form — staff should be able to update text and images."
The agent will design the page with Tilda blocks, configure form webhooks, add custom CSS for brand consistency, and set up analytics tracking.
User prompt: "Add a pricing calculator and interactive product comparison table to our Tilda site."
The agent will create Zero Block layouts with custom HTML/JS for the calculator and comparison table, styled to match the Tilda theme.
User prompt: "Send every form submission to our CRM and notify the sales team on Telegram."
The agent will configure Tilda webhooks, create a serverless function to receive submissions, and forward data to CRM + Telegram.