Deploy / build (push) Successful in 19s
The crawler/sitemap mechanics now live in the repo doc, not just in the commit log: robots.txt is a build-time endpoint that must stay pure ASCII (no charset on a text/plain response means non-ASCII renders as mojibake), the policy is allow-all with enforcement deliberately left to Cloudflare, why writing a real robots.txt demotes Cloudflare's placeholder from replacement to prepend, and that lastmod/hreflang are derived so they must never be hand-authored.
4.1 KiB
4.1 KiB
SEO & Metadata Reference — blog.hoelee.com
Operational reference for the SEO/GEO decisions baked into this project. Read when adding posts, changing <head> markup, or debugging search visibility.
Two-lane strategy (2026)
Optimize for both:
- Classic SEO — Google blue links (still the majority of name searches).
- GEO (Generative Engine Optimization) — getting cited by Google AI Overviews, ChatGPT Search, Perplexity. They pull from well-structured, question-answering content.
Identity & E-E-A-T (do this first, once)
The entire blog strategy is a name-search play, so identity must be airtight:
- One name everywhere: "Lee Teong Hoe" / "Mr Hoelee" — pick one and keep it identical on blog, LinkedIn, GitHub, git.hoelee.com.
- One photo across all profiles.
sameAshandles in thePerson/ProfilePageschema → LinkedIn, GitHub, git.hoelee.com.ProfilePageschema wrapping every post's author bio — how Google connects my writing to my professional identity.
Per-post checklist
- Unique title ≤ 60 chars (target keyword near front)
- Meta description ≤ 155 chars
- Canonical URL set
- Custom
og:image(1200×630) — never the reused logo og:image:width/heightdeclared (else WhatsApp/Telegram/LinkedIn reject the preview)twitter:card: summary_large_image- Category + tags set
- Author card present
- Internal links to ≥1 pillar post
Structural checklist (site-wide)
sitemap.xml+robots.txt+ RSS — auto-generated by Astro- Core Web Vitals 90+ (verify Lighthouse on 390px and 1280px)
- Question-shaped H2/H3 (the phrasing a learner actually searches)
- Related-posts module (3 cards) on every post
- No orphaned/thin pages (avoid the hoelee.com ~400-attachment mistake)
Crawler / sitemap mechanics (as built)
robots.txtis a build-time endpoint (src/pages/robots.txt.ts), not a static file inpublic/. It interpolatesSITE.urlso theSitemap:line can't drift. Keep it pure ASCII — the response has no charset, so a non-ASCII byte renders as mojibake (鈥�) in viewers that fall back to a legacy codepage. Check:LC_ALL=C grep -c '[^ -~]' dist/robots.txtmust be0.- Policy is allow-all, including AI training crawlers. Rationale:
robots.txtis advisory and unenforced (Cloudflare documents it as voluntarily honoured), so a blocklist there buys nothing; enforcement, if ever wanted, belongs in Cloudflare AI Crawl Control./pagefind/is the only exclusion (build artifacts, not content). - Why a real robots.txt matters at all: writing one turned Cloudflare's Content Signals Policy placeholder from a replacement into a prepend. On a Free-plan zone with no origin
robots.txt, Cloudflare serves that placeholder in place of your file — a comment block with noUser-agent, no directives and noSitemap:line. Confirm the origin is serving yours before blaming Astro. - Sitemap
lastmod+xhtml:linkhreflang alternates are derived, never authored — see the rule in the project skill.sitemap-index.xmllegitimately contains exactly one entry (sitemap-0.xml) and looks empty in a viewer; the URLs are insitemap-0.xml(77 of them at 29 posts). Don't "fix" the index. - hreflang exists in two places on purpose: in-page
<link rel="alternate">(fromBaseLayout'saltLocaleUrl) and sitemapxhtml:link. Google treats the sitemap as more authoritative when they disagree, so both must be kept in sync — which is automatic for posts and for any page that passesaltLocaleUrl.
Syndication policy
- Primary home = this domain (own the SEO).
- Cross-post to Dev.to / Medium with a
rel=canonicalpointing back to blog.hoelee.com — reach without platform lock-in. - Never make a third-party platform the primary host.
The "hard job → post" GEO framing
When writing, phrase the opening as the exact question someone types into an AI engine or Google:
"How do I set up site-to-site OpenVPN behind CGNAT?"
Then answer it directly with clear H2/H3 headings. This is what both Google and the AI engines cite.