SEO Implementation Strategy Using JSON-LD Schemas for Articles and FAQs in Developer Roadmap

The Developer Roadmap site boosts search visibility by dynamically generating JSON-LD structured data for every roadmap page, combining BlogPosting schemas for articles with FAQPage schemas for question-answer pairs.

The kamranahmedse/developer-roadmap repository uses a server-side SEO implementation strategy that injects Schema.org markup directly into the HTML head. By leveraging TypeScript helpers to construct JSON-LD objects, the site ensures that search engines receive rich, structured metadata about each roadmap's content, publication dates, author information, and associated FAQs.

How JSON-LD Schemas Power SEO in Developer Roadmap

Structured data enables search engines to display rich results—enhanced listings that include article previews, publication dates, and expandable FAQ snippets. The implementation relies on two core utilities in src/lib/jsonld-schema.ts:

  • generateArticleSchema – Constructs a BlogPosting object containing the roadmap's headline, description, image, author, and timestamps.
  • generateFAQSchema – Transforms roadmap questions into a FAQPage entity with Question and Answer pairs.

These helpers are consumed by src/pages/[roadmapId]/index.astro, which orchestrates data fetching, schema assembly, and injection into the page layout.

Generating Article Schemas with generateArticleSchema

The BlogPosting Schema Structure

The article schema follows the Schema.org BlogPosting specification, providing search engines with comprehensive metadata about the roadmap content. The generated object includes:

  • Context and Type: @context set to https://schema.org and @type as BlogPosting.
  • Main Entity: A WebPage reference linking to the canonical URL.
  • Content Metadata: headline, description, and image properties derived from the roadmap data.
  • Attribution: author (Person) and publisher (Organization) objects with names, URLs, and logos.
  • Temporal Data: ISO 8601 formatted datePublished and dateModified strings generated using luxon.

Implementation in src/lib/jsonld-schema.ts

The helper function accepts an ArticleSchemaProps object and returns a strict Schema.org-compliant JavaScript object:

export function generateArticleSchema(article: ArticleSchemaProps) {
  const { url, headline, description, imageUrl, datePublished, dateModified } = article;
  return {
    '@context': 'https://schema.org',
    '@type': 'BlogPosting',
    mainEntityOfPage: {
      '@type': 'WebPage',
      '@id': url,
    },
    headline,
    description,
    image: imageUrl,
    author: {
      '@type': 'Person',
      name: 'Kamran Ahmed',
      url: 'https://twitter.com/kamrify',
    },
    publisher: {
      '@type': 'Organization',
      name: 'roadmap.sh',
      logo: {
        '@type': 'ImageObject',
        url: 'https://roadmap.sh/img/brand-square.png',
      },
    },
    datePublished,
    dateModified,
  };
}

Building FAQ Schemas with generateFAQSchema

Mapping Questions to Schema.org Format

The FAQ schema implementation targets Google's FAQ rich result format. Each roadmap may contain multiple FAQ entries stored in the questions array. The system filters for items with type: 'faq' and transforms them into Schema.org Question entities containing nested Answer objects.

Rendering Markdown to Plain Text

Since FAQ content is stored as markdown but JSON-LD requires plain text, the helper uses renderMarkdownFromJson to strip formatting and join content into a single string:

export function generateFAQSchema(faqs: OfficialRoadmapQuestion[]) {
  return {
    '@context': 'https://schema.org',
    '@type': 'FAQPage',
    mainEntity: faqs.map((faq) => ({
      '@type': 'Question',
      name: faq.title,
      acceptedAnswer: {
        '@type': 'Answer',
        text: renderMarkdownFromJson(faq.description, { join: ' ' }),
      },
    })),
  };
}

Integrating Schemas into Roadmap Pages

Data Fetching in [roadmapId]/index.astro

The orchestration happens in src/pages/[roadmapId]/index.astro, which serves as the entry point for all roadmap pages. The component executes the officialRoadmapDetails GraphQL query to retrieve metadata including title, description, createdAt, updatedAt, and the questions array.

Assembling the JSON-LD Array

The page constructs a jsonLdSchema array and conditionally pushes schemas based on available data:

let jsonLdSchema = [];

jsonLdSchema.push(
  generateArticleSchema({
    url: `https://roadmap.sh/${roadmapId}`,
    headline: roadmapData?.seo?.title || roadmapData?.title?.page,
    description: roadmapData?.description,
    datePublished,
    dateModified,
    imageUrl: `${baseUrl}/roadmaps/${roadmapId}.png`,
  })
);

if (faqs.length) {
  jsonLdSchema.push(generateFAQSchema(faqs));
}

Injecting into BaseLayout

Finally, the assembled array is passed to src/layouts/BaseLayout.astro via the jsonLd prop. The layout serializes the array and injects it into the document head as a <script type="application/ld+json"> tag, making the structured data immediately available to search engine crawlers.

Summary

  • Dynamic Generation: The Developer Roadmap site generates JSON-LD schemas server-side for every roadmap page using generateArticleSchema and generateFAQSchema in src/lib/jsonld-schema.ts.
  • Dual Schema Approach: Each page combines a BlogPosting schema (describing the roadmap content) with an optional FAQPage schema (representing attached questions), maximizing rich result eligibility.
  • Astro Integration: The implementation leverages Astro's server-side rendering in src/pages/[roadmapId]/index.astro to fetch data, assemble schemas, and inject them via BaseLayout.astro.
  • Content Transformation: FAQ answers are converted from markdown to plain text using renderMarkdownFromJson to ensure valid Schema.org markup.

Frequently Asked Questions

How does the Developer Roadmap site generate JSON-LD structured data?

The site uses two TypeScript helper functions, generateArticleSchema and generateFAQSchema, located in src/lib/jsonld-schema.ts. These functions construct Schema.org-compliant objects that are assembled into an array and injected into the page head as a <script type="application/ld+json"> tag via the BaseLayout.astro component.

What types of Schema.org schemas are implemented for SEO?

The implementation primarily uses two schema types: BlogPosting for the roadmap article itself (containing headline, description, author, publisher, and timestamps) and FAQPage for collections of frequently asked questions. The FAQ schema contains nested Question and Answer entities that enable rich Q&A snippets in search results.

Where does the JSON-LD injection happen in the codebase?

The injection occurs in src/pages/[roadmapId]/index.astro, which fetches roadmap data via GraphQL, constructs the schema array, and passes it to src/layouts/BaseLayout.astro through the jsonLd prop. The layout component then serializes the data and renders it within the HTML <head> section.

How are FAQ answers processed before being added to the schema?

Since FAQ content is stored as markdown but JSON-LD requires plain text strings, the generateFAQSchema function processes each answer using renderMarkdownFromJson. This utility strips markdown formatting and joins the content into a single space-separated string, ensuring the resulting Schema.org markup is valid and crawler-friendly.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →