Blog Rendering Guide

This document explains how the blog works in this project, specifically:

Files Involved

Supporting components used by these pages:

1) How /blog Works (index.astro)

Data loading

index.astro does:

  1. getCollection("blog", ({ data }) => !data.draft)
  2. Sorts posts by date descending (newest first)
  3. Picks:

This means the newest non-draft post becomes the featured card, and all others go into the grid.

Rendering structure

The page renders in this order:

  1. BlogHero
  2. BlogFilterBar (uses categories = ["All", "Startups", "SMEs", "AI", "Healthtech"])
  3. Featured section with BlogFeaturedCard post={featuredPost}
  4. Grid section with remainingPosts.map((post) => <BlogGridCard post={post} />)
  5. Empty-state container (#no-results) for filtering fallback
  6. BottomCTA
  7. WhatsAppFAB

Important behavior notes

2) How /blog/[slug] Works ([slug].astro)

Static path generation

[slug].astro uses getStaticPaths():

  1. Fetches all non-draft blog posts.
  2. Returns one path per post:
{
  params: { slug: post.id },
  props: { post }
}

So each post id becomes a route like /blog/<post.id>.

Page data setup

For each generated page:

  1. const { post } = Astro.props
  2. const { Content, headings } = await render(post)
  3. Computes wordCount from post.body
  4. Loads all non-draft posts again and computes relatedPosts

Related posts are selected when:

SEO schema

The page builds postSchema (BlogPosting) and passes it to Layout.

Includes:

Rendering structure

The single post page renders:

  1. BlogProgressBar
  2. Hero area (breadcrumb, category tags, author, date, read time, title, excerpt)
  3. Featured image (<img> for absolute/root images, <Image> for Astro asset paths)
  4. Main content (<Content />)
  5. BlogSidebar with headings
  6. Optional FAQ block when post.data.faq exists
  7. BlogRelatedPosts
  8. BottomCTA
  9. WhatsAppFAB
  10. BlogScripts

3) End-to-End Data Flow

flowchart TD
  A[src/content/blog/*.md or .mdx] --> B[getCollection('blog')]
  B --> C[/blog index.astro]
  B --> D[getStaticPaths in /blog/[slug].astro]
  C --> E[Featured + Grid cards]
  D --> F[One static route per post.id]
  F --> G[render(post) => Content + headings]
  G --> H[Post page UI + sidebar + related + schema]

4) How a New Blog Becomes Visible

When you add a new non-draft post to the blog content collection:

  1. It is picked up by getCollection("blog").
  2. It appears on /blog (often as featured if newest).
  3. A static page is generated at /blog/<post.id>.
  4. It may appear under related posts for other blogs if categories overlap.

5) Quick Debug Checklist

If a post is not visible:

  1. Check draft: false in frontmatter.
  2. Check frontmatter date format is valid.
  3. Confirm the file is inside the blog content collection path.
  4. Confirm post.id is what you expect for route URL.
  5. Verify categories array exists for related-post/category features.

If /blog/[slug] is not generated:

  1. Confirm it is included in getCollection("blog", ({ data }) => !data.draft).
  2. Confirm build has re-run after content change.