Tenant admin

The problem we were sitting on.

A tenant on Mobieus already has its own subdomain (or custom domain since 2026-05-23), its own brand, its own members, and its own content. What it did not have was its own SEO and analytics surface. If a tenant operator wanted to see how members were getting to threads, they were stuck with whatever the platform exposed. If they wanted Google to crawl new content faster, they could not submit a property in Search Console because we had no way to inject the verification meta tag. And if they wanted to keep AI crawlers out, they had no robots.txt knob.

That was fine when Mobieus was running three internal tenants. It is not fine for Pro and Sovereign customers running their own brands. So we built the full set in one push.

What shipped

Analytics injection: GA4, GTM, Plausible, Fathom, PostHog.

Pick a provider in /admin/branding, paste the ID, save. Mobieus injects the right script tag on every page server-side: G-XXXXXXXXXX for GA4, GTM-XXXXXXX for Tag Manager, your domain for Plausible, your site code for Fathom, the project key plus instance host for PostHog. The form accepts more than one provider at a time, in case you want GA4 for the marketing team and Plausible for yourself. Every input has a /D-anchored regex validator so a stray newline or backtick can't smuggle script content past sanitization.

Search engine verification: Google + Bing.

Paste the Google Search Console verification token (the long random string from the HTML-tag method) and the Bing Webmaster Tools token. Mobieus injects the corresponding <meta name="google-site-verification"> and <meta name="msvalidate.01"> tags into every page head. We sanitize aggressively: only the token charset is allowed; everything else is rejected at validation time. Verification is the cheapest SEO investment a tenant can make, so we made it a one-paste affair.

robots.txt editor with auto-generated default.

If you do nothing, the tenant serves a sensible default robots.txt that allows search bots, points to the sitemap, and disallows the obvious internal paths (/admin, /api, /auth). When you do want to edit it, click into /admin/branding and you get a textarea with syntax preview. Want to block ChatGPT or Claude from crawling your community content? Flip the AI bot toggle: that injects User-agent blocks for GPTBot, ClaudeBot, CCBot, Google-Extended, anthropic-ai, and the rest of the named-AI list. Want to allow them? Leave it on.

llms.txt editor.

llms.txt is the emerging convention for telling LLMs what a site is about. Mobieus auto-generates one for every tenant containing the site name, tagline, a short blurb, and links to the top forums, pinned threads, and the about page. The editor lets you rewrite it. We do the same auto-generation logic our marketing site uses on www.mobieus.io.

Dynamic sitemap.xml with force-refresh.

The tenant sitemap is now generated from live data: every forum index, every public thread, every published guide, every published file listing, every event detail page. Each entry carries a real <lastmod> based on the underlying record's updated_at. The sitemap is cached and rebuilt on schedule, but the admin can force-refresh and ping IndexNow with one button in /admin/branding. IndexNow tells Bing and Yandex about new URLs in seconds instead of days.

AI bot toggle, surfaced as a checkbox.

Whether you allow AI crawlers is a brand decision. Some tenants want their content to show up in AI answers because it drives discovery. Others want their members' threads to stay out of training corpora. The toggle in /admin/branding is honest about what it does: it adds the named-AI blocks to robots.txt and sets X-Robots-Tag headers that defeat the AI crawlers we know about. We do not pretend it stops every scraper, because no robots-honoring directive does.

How it works under the hood

One sanitizer, many tags.

All seven inputs (GA4, GTM, Plausible, Fathom, PostHog, GSC token, Bing token) route through a single class called MetaTagSanitizer. It owns 27 unit tests covering valid inputs, lookalike inputs, injection attempts ("><script>, CRLF, NULL byte, backticks), trailing whitespace, and the full Unicode lookalike set. The /D modifier on every regex anchor closes the trailing-newline vector that bit us once before in the input layer.

Server-side injection, not client-side.

We inject the tags server-side at template render time, not from a client-side bootstrap script. Two reasons: blockers can defeat client-side injection, and a server-rendered tag fires before the page paints, which matters for analytics deduplication. The CSP allowlist for Plausible, Fathom, PostHog, and the GTM endpoint ships with the feature so the tags are not blocked by our own policy.

From /admin/config to /admin/branding.

The first cut of analytics + SEO landed in /admin/config because that is where most environmental settings live. That was wrong. SEO, analytics, social-card overrides, and verification tokens are all branding choices, not platform configuration, so we moved them. The reconciliation collapsed seven duplicate keys, ran a one-off migration across all three tenants to merge old values, and updated the admin nav. The story is dry but the lesson is: if a setting reads more like a brand decision than a platform setting, the brand admin should own it.

Pings, not polls.

When you save analytics IDs, change robots.txt, or hit force-refresh on the sitemap, Mobieus pings IndexNow with the new URLs immediately. The IndexNow keyfile is auto-generated the first time you submit a key, so a tenant can move from zero to verified in two clicks. We do not retry pings that fail; IndexNow accepts duplicates without complaint and the next sitemap refresh will pick up anything missed.

What this means for operators

If you run a Pro or Sovereign tenant, your /admin/branding now has the controls you were filing tickets for. GA4 in two minutes. Plausible in two minutes. Search Console verified in five. Force a sitemap refresh after a big content push. Lock down AI crawlers if your members want their threads private. Open them up if you want LLM answers to cite you.

The feature shipped enabled, with sensible defaults across all three live tenants. If you have not touched /admin/branding yet, your tenant is serving the auto-generated robots.txt and llms.txt, plus a default sitemap built from live data. Anything you change overrides; anything you leave alone keeps working.

Spot a bug, want a provider we missed (Matomo is on our list), or have a Search Console question? Open a thread at support.mobieus.io/forums/feature-requests.