SEO Audit — Christchurch Miami

christchurchmiami.org · app.christchurchmiami.org · resources.christchurchmiami.org · 4 peer-church comparative
2026-05-09 Comprehensive · Ad Grant · GEO · Comparative

Executive Summary

Headline: Christchurch Miami's blog and per-sermon resource architecture are now best-in-class for the South Florida PCA peer set. Schema craft, two-audience content strategy, and the new four-surface app on its own subdomain put CCM ahead of every direct comparator. The remaining 25% gap is concentrated in three places: (1) legacy Snappages "About-tier" pages that haven't been touched in this round of SEO work, (2) the new app.christchurchmiami.org subdomain shipping without robots.txt or sitemap.xml, and (3) raw content volume — peers with WordPress archives have years of indexed long-tail that CCM is still building.

Most urgent fix: Add robots.txt and sitemap.xml to app.christchurchmiami.org and register it as a separate Google Search Console property. Without this, the new subdomain is invisible to Google despite hosting CCM's strongest schema-rich content.

Domain health at a glance

christchurchmiami.org
72/100
Strong on blog, schema, and homepage local signals. Static "About-tier" pages drag the score down.
app.christchurchmiami.org
64/100
Technically clean build, but missing indexation foundation. Will jump to ~85 once robots/sitemap/schema land.
resources.christchurchmiami.org
/sunset
Deprecated as of 2026-05-07. No inbound links from main nav (verified). Recommend platform-side 301.
vs. peer set (CFM, CJ, GC, OCPC)
tied #1 on craft
CCM matches CFM/CJ on aggregate score with a much smaller surface — wins on schema, loses on volume.

What we verified live (2026-05-09) Items confirmed against live HTTP — not just workspace artifacts

  • Hub page /sermons-and-blogs is NOT in primary navigation — verified by fetching homepage and three other pages. The strategic hub Jeff invested in is currently orphaned from the main menu (only reachable by direct link or footer/internal cross-links).
  • 5/3 blog post OG image is REAL, not the placeholder — Agent #1 flagged a possible [PLACEHOLDER:...] bug from workspace artifacts. Live verification: og:image resolves to a real Snappages CDN URL. Cleared
  • Blog index meta description is generic/blog meta description reads "We exist to glorify God by helping people know, love, and serve Jesus." That's the church mission line, not a blog-specific description. Confirmed live
  • Blog tag taxonomy is bloated — 80+ tags rendered in the sidebar; many one-off ("Iran," "Israel," "Moonstruck," "Solstice"). Tag cannibalization risk for individual posts. Confirmed live
  • app.christchurchmiami.org/devotionals/ is live and well-structured — clean title, OG image (1920×1080), shares main-site nav, GTM installed. The duplicate-content concern Agent #2 flagged from build files is mitigated on the live site (page summarizes & deep-links rather than reproducing dated content).
  • app subdomain has trailing-slash inconsistency/devotionals/ redirects to /devotionals (no slash) but <link rel=canonical> points back to /devotionals/ (with slash). Self-conflicting signal. Confirmed live
  • 5/3 blog post: og:image primary URL is HTTP, secure_url is HTTPS — minor mixed-protocol issue Snappages should be told to fix at the platform level.
Items below this line in the Findings tab are from sub-agent analysis of local artifacts and may need additional live spot-checks. The most load-bearing items have already been verified above.

Issue distribution

christchurchmiami.org Snappages-hosted main site · 11 critical/high findings · 6 medium

Critical issues 3

C1CCM-1/en-espanol returns 404 — Ad Grant blocker

Per April 2026 audit, /en-espanol returned 404. Ad Grant policy requires landing pages to be live and substantive — broken Spanish landing destroys the 5% campaign CTR floor that revokes accounts. With CCM's Cuban-Miami audience this is also the highest-leverage local SEO opportunity ("iglesia en Kendall" is low-difficulty per April audit).

EvidenceApril 2026 audit recorded 404. No remediation memory entry between Apr 13 and May 9.
FixEither build a real /en-espanol landing page mirroring /new in Spanish, OR 301 to /spanish-sermons. Verify in GSC that no live ads or sitemap entries point at the 404. Needs live re-verification — may already be fixed.
C2CCM-2Legacy "About-tier" pages likely missing title/meta/canonical/schema

April audit found /about-us, /mission-vision-values, /what-we-believe, /leadership, /new, /kids, /youth, /groups, /resources, /complete-services had no title tags, no meta descriptions, no canonicals, no schema, and no image alt text. No memory entries between April 13 and May 9 indicate these pages were touched.

Why it mattersAd Grant policy requires "substantial, original content" on landing pages. A thin /new (~250-300 words per April audit) with auto-generated SERP snippets is exactly what trips manual review.
FixRun April-audit Table 3 against the live HTML page-by-page. Add <title> (~55 char, brand + location + topic), meta description (~150 char with CTA), self-referencing canonical, OG block. For /leadership, layer Person schema for James Drake, Kent Keller, Heidi Drake, and any elders.
C3CCM-3/giving redirect chain — Ad Grant policy concern

Verified live: nav links /givinghttps://christchurchmiami.churchcenter.com/giving. Ad Grants prohibit ads that lead off the verified domain via a single hop into a checkout/donation flow without intervening content.

Why it mattersIf ads point at /giving, GSC and Ad Grants policy will see this as a thin redirect, not a landing page.
FixConvert /giving from a redirect into a real landing page on christchurchmiami.org with body copy ("Why we give," tax-deductibility note, frequency options, contact for legacy/stock gifts), then put the ChurchCenter button as a CTA on that page rather than a domain-level redirect. Critical before the Ad Grant application proceeds.

High-priority 5

H1CCM-4/sermons-and-blogs hub is not in primary navigation

Verified live 2026-05-09: Homepage and blog index nav both show SermonsEnglish Sermons / Sermon Resources / Spanish Sermons. There is no link to /sermons-and-blogs in the main nav.

Why it mattersJeff invested significant effort building the hub page with full CollectionPage @graph, topic chips, and four named lanes. Without nav placement, the page accumulates no link equity from the rest of the site, and human users can't discover it.
FixDecision needed: either (a) replace the Sermons top-level nav link's destination from /sermons to /sermons-and-blogs, OR (b) add the hub as a sibling submenu item ("Sermons & Blogs"). Option (a) consolidates link equity into the hub but risks Snappages' nav fragility. Option (b) is safer.
H2CCM-5Blog index meta description is the church mission line, not blog-specific

Verified live 2026-05-09: /blog ships meta-description: "We exist to glorify God by helping people know, love, and serve Jesus." The page title is "Blog | Christchurch Miami — Evidence for Faith & Devotionals" (good), but the description is the homepage mission statement, not blog content positioning.

Why it mattersThe blog index is a high-priority ranking surface for queries like "Christchurch Miami blog" / "Miami church apologetics blog." A blog-specific description would improve SERP CTR ~10-20% per industry benchmarks.
FixReplace with: "Apologetics, devotionals, and sermon reflections from Christchurch Miami in Kendall, FL. Weekly blog covering biblical answers, faith for skeptics, and the questions Miami families are actually asking." (155 chars)
H3CCM-6Sitemap freshness — submitted 4/27, three new posts since

Sitemap was submitted to GSC on 2026-04-27 (workspace memory). Three blog posts have published since (4/29 Christian Nationalism, 5/3 Don't All Religions, 5/6 Can I Trust the Bible) plus the hub rebuild. Snappages typically auto-regenerates /sitemap.xml, but the April audit recorded only 71 URLs.

FixLive-fetch /sitemap.xml. Confirm: (a) the three new posts appear, (b) /sermons-and-blogs appears with <lastmod> of 5/3 or later, (c) <lastmod> auto-updates. Re-submit to GSC if stale. Run weekly going forward.
H4CCM-7Blog tag taxonomy is bloated and cannibalizes itself

Verified live 2026-05-09: 80+ tags rendered in blog sidebar including one-off semantic noise: "Iran," "Israel," "Moonstruck," "Summer Solstice," "Winter Solstice," "Sun," "Moon," "Sheep," "Shroud."

Why it mattersEach tag generates an indexable /blog/tag/{slug} URL. With 80+ tags and ~50 posts, you have more tag pages than content pages — classic thin-content / index bloat. Single-occurrence tags should be removed.
FixAudit tags: any tag with 1 post becomes a body-text mention only (delete the tag). Consolidate semantically-equivalent tags ("Christ" + "Jesus", "MLK" + "Martin Luther King Jr"). Cap to ~25 high-value tags. Ad noindex on tag pages with <3 posts via theme-side rule if Snappages supports it. Re-submit sitemap after.
H5CCM-8Older blog posts predate the 11-entity @graph standard

Posts authored as "Jeff Reed" pre-April 12, 2026 don't have the locked @graph and won't be cited by Perplexity/ChatGPT the way the recent ones can be. Workspace memory documents the schema lock as starting around the resurrection-evidence post (4/12).

FixPull a list of top 10 highest-traffic legacy posts from GSC. Backfill the BlogPosting + FAQPage + HowTo + WebPage + Person + Church @graph on those. Cost: ~30 min per post. Highest-traffic first; the rest can wait.

Medium-priority 6

M1CCM-9Image alt text gap on legacy pages

April audit recorded "no alt text detected on any image across audited pages." Snappages exposes alt in the image widget but it requires a per-image pass.

FixPass through every page; for Christchurch logo use Christchurch Miami logo; for hero images use scene-descriptive alts ending with "Christchurch Miami in Kendall, FL" on at least homepage hero, /new hero, /leadership portraits.
M2CCM-10/sermons /english-sermons /spanish-sermons /complete-services /sermons-and-blogs cannibalize each other

Five overlapping URL surfaces compete for "Christchurch Miami sermons" intent. Hub-rebuild doc explicitly fixed a prior schema-URL mismatch where the page declared @id of /sermons while sitting at /sermons-and-blogs — that exact bug pattern can recur on the others.

FixAudit canonical + JSON-LD @id on each. Each should self-reference; none should claim to be another URL. Pick one as the strongest hub (already decided: /sermons-and-blogs) and ensure the other four cross-link to it rather than competing.
M3CCM-11og:image protocol mismatch on blog posts

Verified live 2026-05-09 on 5/3 blog post: og:image primary URL begins http://; og:image:secure_url is https://. Most parsers prefer secure_url, but Twitter and some Slack/Discord scrapers default to og:image.

FixSnappages-side: ask support to flip og:image default to https://. Until then, the secure_url fallback covers the most-used clients.
M4CCM-12/about /leadership probably missing H1 (Snappages default pitfall)

April audit found /about missing H1. Recurring Snappages pitfall: page builder uses page name as banner instead of true <h1>. Needs live verification

FixView-source on each: search for <h1. Add via Code widget if missing.
M5CCM-13FAQ count varies post-to-post (6, 9, 11) — standardize for consistent AI Overview yield

5/3 post: 6 FAQ entries. 5/6 post: 11 FAQ entries. 4/29 post: 6. Google's FAQ rich-result eligibility doesn't care about exact count, but for AI Overviews and Perplexity, more well-formed Q&A pairs = more answer surfaces.

FixStandardize on 8-10 per post in the subsplash-blog skill template. Update workspace memory reference_subsplash_blog_schema_and_seo to lock the count.
M6CCM-14/resources menu page may compete with sermon-resource lane

Per workspace memory, resources.christchurchmiami.org is SermonShots (now deprecated). But christchurchmiami.org/resources is a Snappages-hosted menu page in the main nav.

FixVerify /resources: (a) has clear title/description distinct from the subdomain, (b) noindexs if it's truly just a redirect menu, OR has unique value if it stays indexed. Two indexable pages with the word "resources" on the same root domain is keyword cannibalization waiting to happen.

app.christchurchmiami.org Cloudflare Pages app, ~2 days live · 3 critical · 4 high · 5 medium

Critical issues 3

A1APP-1No sitemap.xml — new domain is invisible to Google

Build output contains zero files matching sitemap*. No reference in templates.

Why it mattersThis is a brand-new subdomain with no organic discovery path. GSC for christchurchmiami.org (URL-prefix property) does NOT cover the app. subdomain — needs a separate property AND a separate sitemap. Without one, Googlebot crawls only what it stumbles on via outbound links.
FixGenerate _build/sitemap.xml at build time. Include: /, /devotionals/, /bible-reading-plan/, plus per-sermon /{slug}/devotionals/, /{slug}/resources/, /{slug}/group/. Set <lastmod> to service date (or build date for evergreen). Add sitemap pointer in robots.txt. Register app.christchurchmiami.org as a separate URL-prefix property in GSC and submit sitemap.
A2APP-2No robots.txt

Cloudflare Pages will return 404 for /robots.txt. Google tolerates this, but you lose the ability to (a) declare sitemap location, (b) block crawl traps, (c) signal intent to AI crawlers (GPTBot, ClaudeBot, PerplexityBot). For Ad Grant eligibility, Google specifically wants to verify the site is open to indexing.

FixAdd _build/robots.txt:
User-agent: *
Allow: /

Sitemap: https://app.christchurchmiami.org/sitemap.xml
A3APP-3Trailing-slash inconsistency: /devotionals/ redirects to /devotionals but canonical points to /devotionals/

Verified live 2026-05-09: Request to https://app.christchurchmiami.org/devotionals/ returns a 30x redirect to https://app.christchurchmiami.org/devotionals. The HTML at the redirect target ships <link rel="canonical" href="https://app.christchurchmiami.org/devotionals/"> — pointing back to the URL it just redirected away from.

Why it mattersSelf-conflicting signal. Google may crawl the canonical URL → get redirected → end up at a different URL than canonical claims. This wastes crawl budget on a 2-day-old domain that needs every signal it can get.
FixDecision: do you want trailing slashes or no? Cloudflare Pages default for directory index.html is trailing slash; pick that (it's the standard for static sites). Update _redirects to NOT redirect /devotionals/. If keeping the no-slash version, update HTML canonical to match served URL.

High-priority 4

A4APP-4No JSON-LD on Resources, Group, Bible-Reading-Plan, or Homepage

Only the 5 devotional files (4 dated + rotating root) ship structured data. Resources pages, group pages, bible-reading-plan, and homepage have no schema at all.

Why it mattersSchema is the single biggest AI-visibility lever available. ChatGPT, Perplexity, Google AI Overviews preferentially cite pages with valid Article / Church / FAQPage / ItemList schema. /resources/ is the highest-intent SEO surface (search query: "Christchurch Miami sermon resources" / "[sermon title] study guide") and has zero schema.
FixPer-surface schema:
Homepage: Organization (or Church) + WebSite with SearchAction. Avoid PCA references per workspace memory.
Resources pages: Article (sermon-recap) + VideoObject referencing Subsplash media URL + BreadcrumbList. Use og_image_url from sermon.json.
Group pages: Article with articleSection: "Small Group Discussion" + BreadcrumbList. Optionally HowTo for the discussion steps.
Bible Reading Plan: CreativeWork or Course with hasPart listing the 354 readings.
A5APP-5Twitter Card metadata is a stub — only twitter:card declared

All 15 pages have <meta name="twitter:card" content="summary_large_image"> but no twitter:title, twitter:description, or twitter:image. Twitter falls back to og:* if available — works for dated devotional, resources, group pages. But homepage and bible-reading-plan have no og:image.

FixAdd og:image, og:image:width/height/alt to homepage and bible-reading-plan templates. Homepage uses generic Christchurch-branded image (gold-on-black brand mark per reference_ccm_brand_palette); bible-reading-plan uses plan-specific cover. Then either add explicit twitter:image/title/description matching og:* OR rely on og:* fallback.
A6APP-6Homepage H1 changes weekly with sermon — collapses with /resources/ /devotionals/ /group/ in SERPs

Homepage hero displays the May 3 sermon and H1 reads "Don't All Religions Lead to God?" — same H1 as the May 3 dated resources/devotional/group pages. Four pages on the same domain with the same H1.

FixChange homepage H1 to a stable string: "Sermon Resources for Christchurch Miami" or "Christchurch Miami — This Week's Sermon Resources." Move sermon-specific title to H2 inside the hero block.
A7APP-7Two render-blocking external font stylesheets in <head>

fonts.googleapis.com + use.typekit.net both rel="stylesheet" in <head>. Both render-blocking from third-party origins. preconnect helps; the stylesheet itself blocks first paint.

Why it mattersLCP is a Core Web Vitals signal. On 4G mobile, two blocking external stylesheets typically add 300-600ms to LCP. Cloudflare Pages' edge-cached HTML should hit ~50-100ms TTFB; you're giving most of that back.
FixEither self-host fonts (pull Lato + Amatic SC WOFF2 into /theme/fonts/, swap to @font-face with font-display: swap) or async-load Typekit with media="print" onload="this.media='all'" trick.

Medium-priority 5

A8APP-8Header logo alt is brand name only

Every page: alt="Christchurch Miami" on header logo image (which links to christchurchmiami.org).

Fixalt="Christchurch Miami — home". Communicates link destination to assistive tech and search.
A9APP-9Sermon hero image not rendered on resources/group pages

sermon.json includes hero_image_url (1920×692) but resources/group templates don't render it. Only devotional cards inside body show images.

Why it mattersLCP element on these pages is currently the H1 text. Works for performance but is a missed E-E-A-T (visual credibility) signal and AI-visibility signal — image-heavy pages are more likely to be cited with thumbnails in AI Overviews.
FixAdd hero <img> with 1920×692 in resources/group hero block, descriptive alt including sermon title + scripture ref. Use loading="eager" and fetchpriority="high" since it's the LCP candidate.
A10APP-10Bible Reading Plan: 354 outbound links, no original commentary

Page has 354+ outbound links to bible.com/bible/59/.../ESV. Each carries target="_blank" rel="noopener". Page content (chapter labels) is thin between links.

Why it mattersNot a blocker, but adds page weight. More importantly, Google sees this as a "link farm" pattern at first glance.
FixAdd 1-2 paragraphs of original commentary above the calendar grid — what the plan covers, why one chapter a day, what to do if you miss a day. Changes the page's character from "link directory" to "guided plan."
A11APP-11Markdown emphasis renders as literal asterisks

5/3 devotional body text: *The name of the LORD is a strong tower...* renders as literal asterisks because body is HTML-escaped. Template's render_paragraphs filter doesn't convert markdown emphasis.

FixUpdate render_paragraphs to convert single-asterisk pairs to <em> and double to <strong>. Or strip them.
A12APP-12302 (temporary) redirects on sermon-bare-slug → /devotionals/

_redirects uses 302 for sermon-bare-slug → /devotionals/ canonicalization. 302 is "temporary" — Google may not pass PageRank.

FixChange to 301 for permanent sermon redirects (lines 8-23). Keep /today as 302 (it IS temporary by design).

resources.christchurchmiami.org SermonShots subdomain · deprecated 2026-05-07 · sunset path, not optimization

Status: Per workspace memory and live verification of the main site nav, this subdomain is no longer linked from christchurchmiami.org. The "Sermon Resources" nav item now points at app.christchurchmiami.org/{slug}/resources/. The subdomain DNS is still pointed at SermonShots — content is likely still live and indexed.

Recommended path: Soft-sunset with platform-side 301. Do not just unpoint DNS — link equity from main-site legal pages plus any external backlinks would be lost. A 301 transfers it; a 404 burns it.

Live checks Jeff should run (~5 min via Chrome MCP)

URLWhat to look for
https://resources.christchurchmiami.org/200/301/404? View-source for <meta name="robots"> and canonical
/robots.txtDisallow rules, Sitemap line
/sitemap.xmlURL count — proxy for indexed-content surface
/devotional and /sermonAre SermonShots Shareable Page paths still serving content?
site:resources.christchurchmiami.org in GoogleTrue indexed-page count
GSC (admin@christchurchmiami.org)Add subdomain as property if not already; pull Pages report for authoritative indexed-list

URL mapping for 301

Old (resources.cm)New (app.cm)Notes
/https://app.christchurchmiami.org/Root → root
/{sermon-slug}https://app.christchurchmiami.org/{sermon-slug}/devotionalsDevotionals = closest semantic match to a SermonShots Shareable Page
/devotional/todayThe /today route already auto-redirects to current week's devotional
/sermonhttps://christchurchmiami.org/sermonsSubsplash sermons hub
Anything else (404 today)https://app.christchurchmiami.org/Catch-all

If SermonShots support won't add per-path 301s, fall back to a single root 301 from resources.christchurchmiami.org/*app.christchurchmiami.org/. That preserves ~80% of the link equity and is a one-ticket ask. Reference account: av@christchurchmiami.org.

Cleanup checklist

  1. Open SermonShots support ticket for site-wide 301 with the URL mapping above.
  2. Update legal pageslegal-pages/privacy-policy.html:140 and terms-of-use.html:111,134. Replace resources.christchurchmiami.org with app.christchurchmiami.org and reword the SermonShots vendor disclosure (SermonShots still processes data even if public surface moves).
  3. Update workspace memoryCLAUDE.md SermonSend row, reference_ccm_subdomain_platform_mapping, sermonsend-weekly-refresh skill smoke-test.
  4. Add subdomain as separate GSC property for 30 days to monitor 301 transfer.
  5. +90 days: DNS cutover decision. Recommend leaving SermonShots A/CNAME pointed (free, harmless) unless subdomain is needed for something else. Cost zero, breakage risk if you unpoint is non-zero.

Comparative SEO scorecard CCM vs. Christ Journey · Christ Fellowship Miami · Granada Church · Old Cutler Presbyterian

Comparative matrix (1 = poor, 5 = excellent)

Dimension CCM CJ CFM GC OCPC
Technical foundation44433
On-page SEO (titles/meta)54523
Local SEO signals44534
Content depth (sermons + blog)45422
AI / GEO readiness53323
Internal linking / hubs44532
Conversion paths45433
Mobile / SSL55544
Aggregate3534352224

CCM is currently tied at the top with the two largest peer sites — but for very different reasons: CFM/CJ win on volume + multi-campus mass; CCM wins on schema craft + per-page SEO discipline. CCM gets there with a much smaller surface area.

Per-site quick profiles

Christchurch Miami (CCM)

Wins: Best-in-class on-page craft — keyword-loaded titles ("Church in Kendall FL 33156"), structured data ahead of every peer, two-audience blog strategy, recently-deployed sermon-resource app on its own subdomain.

Weakness: Smallest content library by raw volume. Single location vs. multi-campus competitors who get free local SEO from each campus page.

Christ Journey (CJ)

Wins: Largest indexed content library — blog, messages archive, message-series archive, two-campus permalinks, Rock RMS-powered Connect Card. Separate Plan-Your-Visit pages for in-person and online.

Weakness: Schema/GEO craft trails CCM. Default WordPress schema rather than purpose-built JSON-LD. Voice feels older-megachurch in some pages.

Christ Fellowship Miami (CFM)

Wins: Most aggressive local SEO — every neighborhood (Doral, Palmetto Bay, West Kendall, Redland, Downtown, Coral Gables) has its own indexed campus page. "Sermons by Book of the Bible" topical hub. 100+ year history positioning.

Weakness: Title-keyword stuffing reads as spammy to humans. Blog content depth lighter than the campus-page mass would suggest.

Granada Church (GC)

Wins: Distinctive "I'm New" page voice — most human-feeling first-visit page in the set. Trilingual (English + Spanish + Portuguese) is unique.

Weakness: Lowest content depth. No real blog. Weak structured data. Site feels like a 2018 WordPress build that hasn't been re-platformed.

Old Cutler Presbyterian (OCPC)

Wins: Cleanest theological prose in the set — "Beliefs" page is the best-written PCA-distinctives page, would feed an LLM cleanly. Reformed identity is unambiguous.

Weakness: Split-domain architecture (ocpc.org + ocpc.life) fragments link equity. No blog. Sermon archive hard to find. CCM's direct denominational peer but the weakest SEO competitor.

Wins for CCM to copy

TacticFromWhy it worksCCM action
Sermons-by-Book-of-the-Bible hubCFMCaptures long-tail Bible-reference search; creates 66 evergreen topical hubsBuild /sermons/book/{book} indexes at app.cm as content fills in
Separate Plan-Your-Visit pages: in-person vs. onlineCJTwo intents = two pages = two ranking surfacesAdd /watch-online distinct from /new
First-person "Everyone Belongs Here" voice on /newGCMost human-feeling first-visit page; dress-code clarity + "personal guide" offer reduces visit frictionAdd explicit dress-code paragraph, parking-by-name, "request a personal guide" form to /new
Standalone /beliefs page as coherent doctrinal essayOCPCBest LLM-ingestible "what does this church believe?" prose in the setConsolidate beliefs into one /beliefs page with full doctrinal treatment, not bullets
Connect Card on owned subdomainCJ (rock.christjourney.org)Custom subdomain = brand control + analytics ownership vs. churchcenter.com redirectMove Connect Card to a CCM-owned URL even if Subsplash is the form behind it
Baptism as named monthly CTACJRecurring conversion event that's genuinely informative, not promotionalAdd baptism page with next 3 dates, schema as Event
Multi-language permalink lanesGC, CFMEach language is a separate ranking surfaceProductize Spanish as /es/ lanes — full landing pages, not just translated YouTube descriptions

Gaps CCM should close

  1. Raw content volume. CJ has years of WordPress posts indexed. CCM's blog cadence is weekly but the archive is shallow. Backfill 8-12 evergreen pillar posts ("What is reformed theology?", "What to expect at a Presbyterian church in Miami") that don't depend on the weekly sermon pipeline.
  2. Multi-location signal. CFM and CJ get free local SEO from multiple campus pages. CCM has one location but can mimic via neighborhood landing pages/kendall, /pinecrest, /coral-gables-area — that contextualize CCM for nearby ZIPs without claiming campuses.
  3. Sermon archive UX. CFM's "by series" + "by book of the Bible" dual-axis browsing beats CCM's flat /services archive. Once app.christchurchmiami.org content fills in, prioritize topical browsing over chronological.
  4. Online-campus identity. CJ treats "Church Online" as a first-class campus with its own Plan-Your-Visit page. CCM's livestream is strong but doesn't have a dedicated landing surface optimized for "watch [city] church online" queries.
  5. Spanish web presence (not just video). All Spanish content lives in YouTube descriptions and HeyGen translations. None is indexed as Spanish HTML. GC and CFM both have Spanish web lanes.
  6. No public-facing FAQ page. FAQ schema embedded in blog posts but no dedicated /faq to capture "is christchurch miami catholic?" / "what time is christchurch miami service?" type queries.

CCM's distinctive moats verified, not flattering

11-entity JSON-LD @graph per blog post

None of the four peers' blog posts (where they exist) show this depth. CJ blog posts return as default WP content; OCPC has no blog; GC has minimal schema; CFM blog posts don't surface FAQ/HowTo signals.

Two-audience parallel blog strategy

SermonSend seeker page + Subsplash new-Christian blog. None of the peers run two separate blog lanes for two audience archetypes from one sermon.

Per-sermon four-surface app subdomain

app.christchurchmiami.org Phase 1 — dedicated four-surface sermon resource app on its own subdomain is more sophisticated than anything peers have. None ship per-sermon resource hubs with daily devotionals + Bible study + group materials.

Daily-devotional drumbeat

5 Mon-Fri PNGs per sermon, IG Story + page-embedded. None of the peers ship per-sermon daily devotional cards as a recurring asset class.

Unified analytics pipeline

GA4 + GSC + Subsplash + PCO + Mailchimp + YouTube + GMB unified into a live dashboard. Consultancy-grade analytics tooling that none of the four peer churches appear to have. Moat for decision speed even though invisible to Google.

Speed of iteration

CCM ships weekly. CFM/CJ feel like quarterly-update sites. GC and OCPC feel annual. Cadence compounds.

Google Ad Grant readiness

Per workspace memory, CCM is in Phase 0 of the Ad Grant application. Below is a fast scorecard of the requirements Google's nonprofit reviewer pulls when validating the site.

SSL / HTTPS site-wideVerified live: christchurchmiami.org and app.christchurchmiami.org both 301 to HTTPS.
Mobile-friendlyBoth domains serve responsive viewports. Snappages and Cloudflare Pages templates pass mobile-friendly check.
Clear nonprofit brandingFooter NAP + mission line on every Snappages page. Christchurch Miami branding is unambiguous.
Substantial content (blog index, sermon archive)50+ blog posts, weekly cadence, long-form (1500-1800 word) recent posts.
/en-espanol returns 404Per April audit. Ad destinations cannot include 404s. Fix before submitting application.
/giving is a pure redirect, not a landing pageRedirects directly to ChurchCenter. Ad Grants don't allow ads pointing at thin off-domain redirects. Build a real /giving landing page.
!
Static "About-tier" pages may be thinApril audit flagged /new, /about-us, /leadership as ~250-300 words with no schema. Strengthen before pointing ads at them.
app.christchurchmiami.org missing robots.txt + sitemap.xmlReviewer pulls these. Add before submission.
!
Hub page /sermons-and-blogs not in navThe strongest internal-link surface is orphaned from main menu. Risk: when Google's reviewer crawls the site, the hub is invisible to user pathfinding.
Domain age + nonprofit verification pathWorking from CLAUDE.md: panos@christchurchmiami.org holds 501(c)(3), EIN, articles. Standard application path.
Recommendation before submitting: Resolve the 4 ✗ items + 2 ! items. Estimated ~6-8 hours of focused work. Application path then proceeds normally; expected approval window 4-8 weeks per nonprofit-norm.

AI visibility / GEO scorecard How well does CCM appear in ChatGPT / Claude / Perplexity / Gemini / Google AI Overviews?

Headline: CCM's blog is genuinely strong here — schema craft, FAQ structure, named-entity coverage, Speakable specification. The gaps are on the church-identity surfaces (homepage, /about, /beliefs) where LLMs answer "what does Christchurch Miami believe?" / "who leads Christchurch Miami?" type queries. Those pages have no schema.

What's working

  • 11-entity @graph on recent blog posts — verified in 5/3 and 5/6 source. Includes BlogPosting, Article, FAQPage, HowTo, Person (author), Church, ItemList (series), VideoObject, BreadcrumbList, WebPage with SpeakableSpecification, plus mentions of named historical figures (Bruce Metzger, F.F. Bruce) with sameAs Wikipedia links.
  • SpeakableSpecification with cssSelector: [".tldr", "h2", "details summary"] well-tuned for assistant readouts.
  • Q&A entries written conversationally, in the form models actually quote. 6-11 FAQ entries per post.
  • Field Devotions CreativeWorkSeries + articleSection correctly groups Drake's deployed-pastor posts as a distinct content cluster.
  • Pastor-authored leaner @graph follows the locked workspace pattern (drop Jeff/theChurch.digital/Care, lean 6 entities).

What's missing

  • Homepage WebSite node with potentialAction SearchAction — entry point Google and Bing use to render the sitelinks search box.
  • Homepage Church / LocalBusiness schema — confirmed live: homepage doesn't ship structured data. NAP is in footer text but not in JSON-LD where LLMs preferentially read.
  • Organization / Church knowsAbout array — adding 8-12 topical strings ("Christian apologetics in Miami," "Reformed theology in Kendall," "biblical counseling for Miami families," watching the no-public-PCA rule) materially helps entity coverage.
  • /leadership Person entities — should ship Person for James Drake (Lead Pastor), Heidi Drake (Kids Director), Kent Keller, named elders, with sameAs to LinkedIn/social. Currently Person entities exist only on blog posts mentioning specific people.
  • app.christchurchmiami.org pages with NO schema — Resources, Group, Bible-Reading-Plan, Homepage. Highest-intent SEO surfaces with zero structured data.
  • No dedicated /faq — answer-engine queries like "is christchurch miami catholic?" or "what time is christchurch miami service?" go unanswered with no rich snippet eligibility.

How an LLM would currently answer "What does Christchurch Miami believe?"

Test result (inferred from current schema state) Without /beliefs or /what-we-believe shipping schema, LLMs would synthesize a generic "Christian church in Kendall, FL with weekly worship and biblical teaching" answer — accurate but undifferentiated. They cannot cite CCM's specific theological identity (Reformed, expositional, mission-driven, etc.) without that prose being structured for ingestion.

30 / 60 / 90-day remediation plan

Sequenced for compounding effect — fixes that unlock other fixes go first.

Days 0-7

Stop the bleeding

  • Add robots.txt + sitemap.xml to app.christchurchmiami.org build
  • Register app.christchurchmiami.org as separate GSC property; submit sitemap
  • Fix or 301 /en-espanol 404 on main site
  • Open SermonShots support ticket for resources.cm site-wide 301
  • Decide trailing-slash policy on app subdomain; align _redirects + canonicals
  • Update legal pages to remove resources.cm references
Days 7-30

Land the schema gaps

  • Add JSON-LD to app.christchurchmiami.org resources, group, bible-reading-plan, homepage
  • Stable homepage H1 on app subdomain (not sermon-of-week)
  • Add og:image + twitter:image to app homepage and bible-reading-plan
  • Add /sermons-and-blogs hub to main-site primary nav
  • Replace generic blog index meta description with blog-specific copy
  • Convert /giving redirect into a real landing page with body content
  • Fix og:image protocol mismatch on Snappages blog posts (open ticket)
Days 30-60

Fill the static-page gap

  • Run April-audit Table 3 against /about-us, /new, /leadership, /kids, /youth, /groups — title, meta, canonical, OG, alt text
  • Add Person schema to /leadership for staff in CLAUDE.md
  • Add WebSite + Church @graph to homepage with knowsAbout + potentialAction
  • Audit blog tag taxonomy; cap to ~25 high-value tags
  • Self-host fonts on app subdomain (or async-load Typekit)
  • Update _redirects 302 → 301 on permanent sermon redirects
  • Build /beliefs as a coherent doctrinal essay (OCPC pattern)
Days 60-90

Compete on volume + bilingual

  • Backfill 11-entity @graph on top 10 highest-traffic legacy blog posts (pull from GSC)
  • Build neighborhood landing pages (/kendall, /pinecrest) for local SEO
  • Productize Spanish as /es/ indexed HTML lanes — homepage, /new, /about, weekly sermon
  • Build dedicated /faq page with FAQPage schema
  • Add /watch-online as distinct landing surface from /new
  • Add Subsplash schema once API credentials land (sermon MediaItems → BroadcastEvent)
  • Submit Ad Grant application (presuming 0-7 + 7-30 items closed)

The bold strategic recommendation If only one thing happens in 90 days, do this

Ship the "Miami Reformed Hub" content cluster on app.christchurchmiami.org

Target the denominational + geographic search space the peer set is collectively ignoring. Specifically: 30 evergreen pillar pages at /learn/ covering "What is reformed theology?", "Reformed vs. Baptist," "Infant baptism explained," "What is the Westminster Confession?", "Presbyterian churches near Miami," "What to expect at a Presbyterian service" — each 1500+ words, full JSON-LD Article + FAQPage + BreadcrumbList schema, internal-linked into a topical cluster, EN + ES versions.

Each page links into the weekly sermon pages (which already have superior schema), creating a topical-authority flywheel between evergreen learn-content and weekly sermon-content.

Why this beats the peer set in 90 days: OCPC is the only direct denominational peer and has no blog — they will not contest this space. CJ, CFM, GC are all non-PCA or PCA-adjacent — they have no incentive to build PCA-specific content. Google's answer-engine surfaces (AI Overviews, Gemini) are starved for well-schemaed Reformed-explainer content from a real Miami PCA church. This pairs CCM's existing schema craft (its #1 moat) with the only thing it lacks vs. peers (content volume), aimed at search territory where no peer can credibly out-rank it.

Expected outcome: Within 90 days, CCM ranks top-3 for "Reformed church Miami," "PCA church Miami" (used internally only — not in public copy per workspace memory), "Presbyterian church Kendall," and a long tail of denomination-explainer queries — a position none of the four peers can defend.