Making a Website AI Agents Can Actually Read: the SEO/GEO Overhaul of fulinlabs.com

· Giovanni Fu Lin · seo, geo, web-performance, astro

The previous version of fulinlabs.com was a Vite + React single-page app: an animated hero, a particle canvas background, and four project cards, all rendered client-side. It looked fine. It was also nearly invisible to anything that doesn’t execute JavaScript — which includes a meaningful share of AI crawlers and social scrapers.

The actual problem

View-source on the old site showed a <title> tag and an empty <div id="root">. Everything a human saw was painted in afterward by React. Crawlers that don’t run a full browser — and that includes GPTBot, ClaudeBot, and most link-preview scrapers — see that empty shell, not the content.

On top of that, one route with about fifty words of visible text meant there was effectively nothing to index, nothing to rank for, and nothing for another site to link to. Domain rating grows from other sites linking to content worth citing; a single animated hero page gives them nothing to cite.

Why a full rebuild instead of a patch

The instinct is to patch: add a prerendering step, bolt on react-helmet for better meta tags, maybe a sitemap plugin. That gets partway to fixing crawlability but does nothing about the second problem — there was no content to prerender. And a React runtime plus animation libraries makes a genuine Lighthouse 100 across Performance, Accessibility, Best Practices, and SEO extremely hard to hit, because the JavaScript itself is the tax.

So the site was rebuilt on Astro with static output: full HTML generated at build time, zero JavaScript shipped to the browser by default. Content — the project hub pages and this blog — lives as plain markdown with frontmatter in the repo, not embedded in components.

What changed, concretely

  • Every page now ships complete HTML with real prose, not a client-rendered shell.
  • Blog posts are portable .md files — no framework-specific syntax, so they could be copied into a different static site generator without rewriting anything.
  • Structured data (Organization, SoftwareApplication, FAQPage, BlogPosting, BreadcrumbList) is attached to every relevant page so both search engines and AI agents have an explicit, machine-readable description of what Fulin Labs is and what each project does.
  • robots.txt explicitly welcomes AI crawlers (GPTBot, ClaudeBot, PerplexityBot, and others) instead of leaving them unmentioned.
  • An llms.txt file gives AI agents a short, direct manifest of the site and its projects.

The result

Zero client-side JavaScript on content pages, real prose on every project and blog page, and a build that targets Lighthouse 100 across all four categories as a hard requirement rather than an aspiration. The technical details of exactly how each budget was hit — image formats, font strategy, CSP headers — are covered in the site’s own overhaul plan, kept in the repo for anyone curious about the specifics.

Read more about the other projects this supports on the projects page.