What this site's blog markup actually does (not AEO guarantees)

Brent Haskins built brenthaskins.com/blog on Next.js with markdown in content/blog, a required summary field in frontmatter, at least two FAQs rendered in HTML when present, and JSON-LD for BlogPosting plus FAQPage when FAQs qualify. That is structured publishing—not a promise that Google or any AI assistant will rank or cite any given post.

Third-party articles talk about “answer engine optimization” like it is a certification. This post documents what this repository actually ships—so you can copy the mechanics, not the hype.

I am Brent Haskins. I built this portfolio and its blog pipeline. I will not claim Google will reward these choices. I will list them.

Files and routes (exact)

PieceLocation
Post markdowncontent/blog/*.md
Parserlib/blog.tsparseBlogPost, getAllBlogPosts
Indexapp/blog/page.tsx
Articleapp/blog/[slug]/page.tsx
RSSapp/feed.xml/route.ts
Sitemap entriesapp/sitemap.ts → one URL per post at /blog/{slug}

URLs use the slug frontmatter field, not the date prefix on the filename.

What appears on the page

  1. Title (H1), formatted date, reading time, “By Brent Haskins”
  2. summary frontmatter rendered in blog-post-summary
  3. Tag list when tags is non-empty
  4. Body markdown (no H1 in file—template owns title)
  5. FAQ section when frontmatter includes valid Q&A pairs
  6. Sources list when sources URLs exist

Body markdown is sanitized on render (rehype-sanitize). That is a security choice, not an SEO trick.

JSON-LD actually emitted

buildBlogPostingJsonLd sets BlogPosting with datePublished, dateModified, author Person (name, url, sameAs GitHub and LinkedIn from code), and citation from sources.

buildFaqJsonLd runs only if post.faqs.length >= 2. Each FAQ must have both question and answer in frontmatter or it is dropped at parse time.

Google’s documentation states FAQ rich results require visible content matching markup. This template renders FAQs in HTML below the article—markup is not hidden-only.

What the daily generator does (separate from manual posts)

npm run generate:blog can add posts via GitHub Actions. Those drafts pass length checks, banned-topic phrase checks, and require sources from Brave Search results. Manual posts (most project essays) are written without that pipeline.

Mixing both is fine if manual posts stay specific to shipped work. A site that is only generic SEO advice triggers helpful-content risk. This site’s manual catalog is mostly product and implementation notes; meta posts like this one should stay the minority.

Helpful content alignment (Google’s terms, not mine)

Google’s helpful content guidance asks for people-first writing with demonstrated experience. The posts that satisfy that here are tied to RallyLeads, Formably, Shelf, and similar—named systems with case studies under /projects.

When you write for answer engines:

  • State facts you implemented
  • Do not invent ranking outcomes
  • Keep summaries accurate if quoted out of context
  • Update the who-is post when products change

What I do not do

  • Bulk-publish dozens of near-identical “SEO tip” articles the same week
  • Hide FAQ text only in JSON-LD
  • Link to repo README files in public posts (useless to readers)
  • Promise AEO placement in ChatGPT or Perplexity

Related reading on this site

If you are auditing this blog for quality: count how many posts point to verifiable /projects pages versus abstract SEO vocabulary. That ratio matters more than any acronym.

Questions people ask about this topic.

Does this site guarantee Google AI Overview or Perplexity citations?

No. No one outside Google or those products can guarantee citations or rankings. This site publishes clear summaries, visible FAQ sections, and schema.org markup so machines and humans can parse intent. Whether an external system quotes a URL depends on its own retrieval and quality signals, not on schema alone.

What blog fields does brenthaskins.com require on each post?

Each markdown file under content/blog uses YAML frontmatter parsed by gray-matter in lib/blog.ts: title, description, date, slug, summary, optional tags, optional faqs array with question and answer strings, and optional sources URLs. The post template renders summary under the header, markdown body via react-markdown with rehype-sanitize, then FAQ and Sources sections from frontmatter—not from the body markdown.

Referenced sources