Monitoring a Tilda site: what you can collect without server access
Every previous article in this series — WordPress, Joomla, 1C-Bitrix, Drupal, OpenCart, MODX — started the same way: install an extension that wires the Sentry SDK into PHP. Tilda doesn’t allow that: it is SaaS, someone else’s server, no PHP at all. So the question changes from “how do we connect everything” to “what is achievable at all”.
The short answer: about half of it — and it is still the useful half.
What you can and cannot have
| Signal | On a CMS with your own server | On Tilda |
|---|---|---|
| JavaScript errors from visitors | yes | yes |
| Web Vitals (LCP, INP, CLS, FCP, TTFB) | yes | yes |
| Uptime and SSL certificate expiry | yes | yes |
| Alerts to Telegram/webhook/email | yes | yes |
| PHP errors on the server | yes | no: not your server |
| Response time per endpoint | yes | no: no backend access |
| Traces and profiling | yes | no |
| Business metrics from the database | yes | no direct DB access |
The “no” rows aren’t a shortcoming of Gotcha but the nature of a site builder: the code on Tilda’s servers isn’t yours, and no monitoring tool can change that. Everything that happens in the visitor’s browser and outside the site, however, is fully available.
And those two groups are usually what’s behind “the site looks fine but no leads are coming in”: a broken form, a script that failed to load, an expired certificate.
Where to get the DSN
After you create a project, Gotcha redirects you to the “Setup” page
(/projects/<id>/setup). The DSN looks like this:
https://<public_key>@gotcha.example.com/<project_id>
The public_key in it is public by design — which is exactly why the DSN can
safely go into the HTML of a page everyone can see.
Where to paste the code
Tilda has a built-in place for arbitrary code in <head>:
Site Settings → More → HTML code for the HEAD section
Whatever goes there lands on every page of the site, which is what monitoring needs. There is also a per-page option (Page Settings → Additional → HTML code in HEAD), but it is pointless for monitoring: errors matter everywhere.
Do not put it in <body> or in a T123 (HTML code) block: the SDK has to
start before the rest of the scripts, otherwise errors thrown before it are
lost. That is the whole reason it lives in <head>.
The code itself
<script src="https://your-host.example.com/sentry.min.js"></script>
<script>
Sentry.init({
dsn: "https://<public_key>@gotcha.example.com/<project_id>",
environment: "production",
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 0.2
});
</script>
browserTracingIntegration collects Web Vitals (LCP, CLS, INP, FCP, TTFB)
on its own and creates the page-load transaction; Sentry.init with no extra
configuration already catches uncaught JavaScript errors and rejected promises.
Where to get the bundle
Modern @sentry/browser doesn’t publish a ready-made browser build to npm — you
build it yourself. Building it once and hosting it next to your own Gotcha
instance (or on any static hosting of yours) is the preferred option:
npm i @sentry/browser esbuild
npx esbuild <(echo "export * from '@sentry/browser'") \
--bundle --minify --format=iife --global-name=Sentry \
--outfile=sentry.min.js
That’s what every extension in this series does: the bundle ships inside the extension rather than being fetched from the internet. For monitoring — whose job is to work when everything else is broken — an extra dependency on someone else’s domain is the wrong trade.
If you have nowhere to host the file, there is Sentry’s official CDN. In that
case always pin an exact version with integrity: without it you are
trusting a third-party server to execute arbitrary code on your site.
<script src="https://browser.sentry-cdn.com/10.69.0/bundle.tracing.min.js"
integrity="sha384-Xl/pZ2YgviohWlNZ2ipnBKfonCQ2EKaXzusUClBh8mrgAiDZa3outR+4H52ZSOz9"
crossorigin="anonymous"></script>
The hash is computed for version 10.69.0 (openssl dgst -sha384 -binary bundle.tracing.min.js | openssl base64 -A). Change the version and you must
recompute it — which is the point: a tampered file simply won’t execute.
Cardinality: the one setting worth thinking about
The browser SDK names the page-load transaction after the URL path. For a
five-page landing site that is ideal: /, /about, /price — exactly what you
want to see in the report.
But if Tilda is hosting a catalogue or a blog with hundreds of pages, the report turns into a wall of rows, one per article. That is the very cardinality problem that makes the extensions name transactions by page type rather than by address.
The cure lives in the SDK — normalise the name before sending:
Sentry.init({
dsn: "https://<public_key>@gotcha.example.com/<project_id>",
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 0.2,
beforeSendTransaction: function (event) {
// /blog/how-we-fixed-nginx -> /blog/:slug
event.transaction = event.transaction
.replace(/^\/blog\/[^/]+$/, '/blog/:slug')
.replace(/^\/catalog\/[^/]+$/, '/catalog/:slug');
return event;
}
});
The rules follow the structure of your particular site; Tilda sites rarely have
many sections, so one or two replace calls are enough. If the site really is
small, there is nothing to configure.
Uptime and SSL: the part that alone justifies this
On Tilda, availability monitoring matters even more than on your own server: you see no logs, no load, and you find out about a problem from a customer. Uptime needs no code whatsoever — Gotcha probes your public URL from the outside:
Uptime → New monitor → HTTP, the site address, interval and failure/recovery thresholds. Incidents, a warning about an expiring SSL certificate and a public status page come out of the box (Uptime).
About the certificate specifically: sites on a custom domain in Tilda get one issued automatically, but renewal problems do happen, and without a monitor you notice them only when a customer calls.
Alerts
In the “Alerts” section the rules (new issue, regression, spike) are enabled already; all that’s left is a delivery channel — Telegram, webhook or email. Channels attach to uptime monitors as well, so a site outage and a new JS error arrive in the same place (Alerts).
What to watch first on a Tilda site
| Metric | Why |
|---|---|
| JS errors per browser | a form or quiz fails to submit for some visitors |
| Errors from third-party scripts | chat and analytics widgets break more often than the site |
| Web Vitals (LCP, INP, CLS) | real speed for real people, not in Lighthouse |
| Uptime | the site is unreachable — know before the customer does |
| SSL expiry | the certificate expires in three days |
Third-party scripts deserve a special mention: a typical Tilda site runs more of them than of its own code — analytics, chats, pixels, calculators. They are what usually breaks, and without monitoring it is invisible: the page looks intact, the button simply doesn’t work.
Summary
- Tilda is SaaS, so the server half of monitoring is out of reach: no PHP errors, no response times, no traces. That’s the builder’s limitation, not the tool’s.
- The browser half is fully available: JavaScript errors and Web Vitals go in with a single block under Site Settings → More → HTML code for HEAD.
- Host the bundle yourself rather than pulling it from someone else’s CDN: monitoring should work when everything else is broken.
- With many pages, normalise transaction names via
beforeSendTransaction, or the report drowns in addresses. - Uptime and SSL need no code at all and matter more on a builder than on your own server: you won’t see the logs anyway.
Next: the documentation, installing Gotcha and the SDK setup section.