The root cause of the schema mismatch was skipIfSchemaCurrent=true in
TinaCMS's syncProject() call, which caused TinaCloud to skip re-indexing
when it thought the schema SHA hadn't changed. This left TinaCloud with
a stale GraphQL schema missing the pages collection (PagesSeo type).
Fix: add an explicit curl step before the build that calls TinaCloud's
reset endpoint WITHOUT skipIfSchemaCurrent, forcing a full re-index.
Keep --skip-cloud-checks in the build command to avoid the circular
dependency (build failing because TinaCloud is still indexing).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--skip-cloud-checks was also skipping syncProject() which is the API call
that tells TinaCloud to refresh its schema. Without it, TinaCloud never
indexed the pages collection, causing 'Expected to find collection named pages'
errors in the admin.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TinaCloud schema validation creates circular dependency in CI when
new types are added. Schema files are committed to git, so TinaCloud
re-indexes via GitHub webhook independently. Skip the build-time check.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add puppeteer + mime-types to devDependencies
- Integrate prerender.mjs into build script (runs after vite build)
- Add Linux/Docker-safe Chrome flags (--disable-setuid-sandbox, --disable-dev-shm-usage, --disable-gpu)
- Fix static server to strip query strings from URLs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New script reads public/blog/posts.json at build time and outputs
public/sitemap.xml with all static routes + /blog/:slug entries,
each with lastmod from post dates or current date.
Build pipeline: sync-blog → generate-sitemap → tsc → vite build
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add tina/config.ts with full schema for all site sections
- Convert i18n from TypeScript to nested JSON (content/translations/)
- Update LanguageContext to import JSON with flattenObject utility
- Update dev/build scripts to run tinacms build
- Add sync-blog.mjs support for content/blog/*.md (TinaCMS posts)
- Update CI/CD with Tina env vars, remove blog rsync exclusion
- Add tina/__generated__/ to .gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add react-helmet-async with SEO component for dynamic meta tags on all pages
- Add JSON-LD structured data (Organization, WebSite, ProfessionalService) to index.html
- Add fallback OG/Twitter Card meta tags in index.html for non-JS crawlers
- Add robots.txt allowing all crawlers including AI bots (GPTBot, Claude-Web, etc.)
- Add sitemap.xml with all routes
- Add llms.txt for AI crawler discovery
- Add X-Robots-Tag header and reviews.json cache rule to nginx.conf
- Replace fake testimonials with Google Reviews (fetch /reviews.json)
- Add star ratings, Google badge, and "Leave us a review" button to testimonials
- Add server/sync-reviews.mjs for daily Google Places API review sync
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
React 19 + TypeScript SPA with Vite, mobile responsive fixes,
GitHub Actions CI/CD pipeline for automated deployment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>