Add Google Search Console verification setting

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 11:42:56 +02:00
co-authored by Claude Opus 5.5
parent 7b2bfc31e6
commit 880e3206cc
6 changed files with 25 additions and 0 deletions
@@ -32,6 +32,12 @@ const TABS: { id: TabId; label: string; icon: LucideIcon }[] = [
const inputCls =
"w-full border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400";
/** The code from Search Console's verification meta tag; accepts the whole tag or just the code. */
function googleVerificationCode(input: string): string {
const m = input.match(/content\s*=\s*["']([^"']*)["']/i);
return (m ? m[1] : input).trim();
}
function Field({
label, hint, required, children,
}: {
@@ -104,6 +110,7 @@ function SiteSettingsPageInner() {
const [orgPhone, setOrgPhone] = useState("");
const [orgAddress, setOrgAddress] = useState("");
const [appBaseUrl, setAppBaseUrl] = useState("");
const [googleVerification, setGoogleVerification] = useState("");
// ── Branding ──
const [primaryColor, setPrimaryColor] = useState("#4F46E5");
@@ -153,6 +160,7 @@ function SiteSettingsPageInner() {
setOrgPhone(s.org_phone || "");
setOrgAddress(s.org_address || "");
setAppBaseUrl(s.app_base_url || "");
setGoogleVerification(s.google_site_verification || "");
// primary_color falls back to the legacy accent_color value (which used
// to be "the one brand color" before this 3-color system existed).
// accent_color is only trusted as the NEW tertiary color once
@@ -209,6 +217,7 @@ function SiteSettingsPageInner() {
org_phone: orgPhone.trim(),
org_address: orgAddress.trim(),
app_base_url: appBaseUrl.trim(),
google_site_verification: googleVerificationCode(googleVerification),
});
const uploadBrandingAsset = async (file: File, kind: "logo" | "favicon"): Promise<string> => {
@@ -432,6 +441,10 @@ function SiteSettingsPageInner() {
<input className={inputCls} placeholder="https://events.yourchurch.org"
value={appBaseUrl} onChange={e => setAppBaseUrl(e.target.value)} />
</Field>
<Field label="Google Search Console verification" hint="In Search Console, add this site as a URL-prefix property and choose the HTML tag method. Paste the tag (or just its content code) here and save, then click Verify in Search Console. Leave it set to stay verified.">
<input className={inputCls} placeholder='<meta name="google-site-verification" content="..." />'
value={googleVerification} onChange={e => setGoogleVerification(e.target.value)} />
</Field>
<SaveBar saving={saving} onSave={saveOrganisation} result={result} />
</div>
)}
+2
View File
@@ -42,6 +42,8 @@ export async function generateMetadata(): Promise<Metadata> {
description,
...(logoUrl ? { images: [logoUrl] } : {}),
},
// Per-deployment Search Console ownership check (Settings → Organisation).
...(settings.google_site_verification ? { verification: { google: settings.google_site_verification } } : {}),
};
}
@@ -25,6 +25,9 @@ export const siteSettingsHelpContent: HelpContent = {
<GuideItem icon={Building2} title="Site URL" tone="gray">
The public URL of this site, used in email links like password resets and ticket delivery.
</GuideItem>
<GuideItem icon={Building2} title="Google Search Console verification" tone="gray">
Proves to Google that you own this site, so you can see search traffic and submit <code>/sitemap.xml</code> in Search Console. Add the site there as a URL-prefix property (e.g. <code>https://events.yourchurch.org/</code>), pick the <strong>HTML tag</strong> method, paste the tag here and save, then click Verify. Each site has its own code. Google finds your events without this; it only unlocks the Search Console reports.
</GuideItem>
</div>
</div>
),
@@ -18,6 +18,7 @@ export type SiteSettings = {
logo_url?: string;
favicon_url?: string;
setup_complete?: string;
google_site_verification?: string;
// Legal pages
legal_operator_name?: string;
legal_io_name?: string;