Skip to content

Feat seo: Structured data markup that Google Search supports#72

Merged
pphatdev merged 6 commits intomainfrom
feat-seo
Mar 13, 2026
Merged

Feat seo: Structured data markup that Google Search supports#72
pphatdev merged 6 commits intomainfrom
feat-seo

Conversation

@pphatdev
Copy link
Owner

@pphatdev pphatdev commented Mar 13, 2026

This pull request adds and improves structured data (Schema.org) across several pages to enhance SEO and search engine understanding. The most important changes include adding breadcrumb structured data to key layouts and pages, introducing structured data for FAQ and software application pages, and refining existing structured data types for better accuracy.

Structured Data Enhancements:

  • Added BreadcrumbStructuredData components to the About, Posts, and Projects pages and layouts, providing search engines with hierarchical navigation information. [1] [2] src/app/posts/[slug]/page.tsxR17, src/app/posts/[slug]/page.tsxR115-R119, [3] [4] [5]
  • Added FAQPageStructuredData to the Home FAQ section, generating FAQPage schema markup for frequently asked questions. [1] [2] [3]
  • Introduced SoftwareApplicationStructuredData component to provide Schema.org markup for software applications, supporting fields like screenshots, repository URL, and keywords.

Schema Type Improvements:

  • Updated the About page structured data from AboutPage to ProfilePage and added more descriptive fields, including @id, name, description, url, dateCreated, and dateModified. [1] [2]
  • Changed the article structured data type from Article to BlogPosting for more accurate representation.

Component Integration:

  • Rendered the FAQ section on the Home page and wrapped it with the BlurFade animation for consistent UI/UX.

Summary by CodeRabbit

  • New Features

    • FAQ section now displays on the home page with smooth animated reveal.
    • Breadcrumb navigation added to posts and projects pages for improved page traversal.
  • Improvements

    • Enhanced structured data across about, article, and FAQ pages with updated schema implementations.

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

📝 Walkthrough

Walkthrough

This pull request integrates JSON-LD structured data throughout the application by adding breadcrumb navigation data to multiple layouts and pages, enabling the FAQ section with schema markup, introducing new structured data components for FAQ pages and software applications, and updating schema types in existing components from AboutPage to ProfilePage and Article to BlogPosting.

Changes

Cohort / File(s) Summary
Breadcrumb Structured Data Integration
src/app/about/page.tsx, src/app/posts/layout.tsx, src/app/posts/[slug]/page.tsx, src/app/projects/layout.tsx
Adds BreadcrumbStructuredData component to render breadcrumb trails with Home, parent category (Posts/Projects), and current page items linked to respective URLs.
FAQ and Home Section Enhancement
src/app/(home)/page.tsx, src/app/(home)/sections/home-faq.tsx
Enables the FAQ section with BlurFade animation wrapper and adds FAQPageStructuredData import to render FAQ schema markup alongside the FaqSection component.
Structured Data Schema Updates
src/components/about-structured-data.tsx, src/components/data-structured/article.tsx
Changes AboutPage schema type to ProfilePage with added metadata fields (\@id, dateCreated, dateModified), and updates Article schema type to BlogPosting for improved search engine compatibility.
New Structured Data Components
src/components/data-structured/faq-page.tsx, src/components/data-structured/software-application.tsx
Introduces two new reusable React components: FAQPageStructuredData for FAQ pages mapping items to Question/Answer pairs, and SoftwareApplicationStructuredData for application metadata including offers, repository, and screenshots.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 Hops with glee through structured data sprinkled,
Breadcrumbs trail and FAQ's tinkled,
Schema blooms in JSON-LD delight,
SEO shines with metadata bright! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective of the pull request: adding structured data markup for SEO purposes across multiple pages and components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-seo
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@pphatdev pphatdev changed the title Feat seo Feat seo: Structured data markup that Google Search supports` Mar 13, 2026
@pphatdev pphatdev changed the title Feat seo: Structured data markup that Google Search supports` Feat seo: Structured data markup that Google Search supports Mar 13, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/components/about-structured-data.tsx (1)

21-22: dateModified computed at render time may not reflect actual content changes.

Using new Date() means dateModified will be the build timestamp (for SSG) or request time (for SSR), not the actual last modification date of the about page content. For accurate SEO metadata, consider:

  1. Using a fixed date that you update manually when content changes, or
  2. Deriving it from git commit dates or CMS metadata at build time.

Additionally, if this component renders on both server and client, there's a minor hydration mismatch risk if the date changes between server render and client hydration (though splitting at 'T' makes this unlikely within the same day).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/about-structured-data.tsx` around lines 21 - 22, The
dateModified field is computed at render time which can be incorrect or cause
hydration drift; update the AboutStructuredData component to accept a fixed
lastModified value (e.g., a prop named lastModified or a build-time constant
like COMMIT_DATE/GIT_LAST_MODIFIED) and use that instead of new
Date().toISOString().split('T')[0]; alternatively derive the date at build time
in getStaticProps or from your CMS/git metadata and pass it into
AboutStructuredData so dateModified reflects the actual content change date.
src/components/data-structured/software-application.tsx (1)

50-54: Consider aligning publisher with the author/creator entity reference.

The author and creator both reference ${NEXT_PUBLIC_APP_URL}#person, but publisher is defined as a separate Person without an @id. If the publisher is the same person, consider using the same reference for linked data consistency:

♻️ Suggested alignment
         "publisher": {
             "@type": "Person",
+            "@id": `${NEXT_PUBLIC_APP_URL}#person`,
-            "name": appName,
+            "name": PERSON_NAME,
             "url": NEXT_PUBLIC_APP_URL
         },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/data-structured/software-application.tsx` around lines 50 -
54, The publisher object currently creates a separate Person while author and
creator reference `${NEXT_PUBLIC_APP_URL}#person`; update the publisher entry in
the structured data to reuse that same reference (e.g., set publisher to
reference the same "@id": `${NEXT_PUBLIC_APP_URL}#person` or assign the existing
author/creator object) so all three (author, creator, publisher) consistently
point to the same linked entity; locate the publisher object in
software-application.tsx and replace its Person literal with the shared `@id`
reference (keeping appName/NEXT_PUBLIC_APP_URL values).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/`(home)/sections/home-faq.tsx:
- Line 25: Update the FAQ item's description prop to correct the grammar:
replace the current string "Everything about this projects." with a
grammatically correct phrasing such as "Everything about this project." in the
description prop (the description= attribute in the home-faq.tsx component).

In `@src/app/posts/layout.tsx`:
- Around line 21-24: The layout currently emits a BreadcrumbStructuredData block
causing duplicate JSON-LD on /posts/[slug] because the post detail page
([slug]/page.tsx) also renders BreadcrumbStructuredData; remove the
BreadcrumbStructuredData invocation from the posts layout (the JSX block that
calls BreadcrumbStructuredData with items [{ name: 'Home'... }, { name:
'Posts'... }]) so only the post detail page's BreadcrumbStructuredData (in
[slug]/page.tsx) emits breadcrumb schema, or alternatively guard the layout call
to render only for the posts index (e.g., when no slug param) so
BreadcrumbStructuredData is not rendered alongside the post detail component.

---

Nitpick comments:
In `@src/components/about-structured-data.tsx`:
- Around line 21-22: The dateModified field is computed at render time which can
be incorrect or cause hydration drift; update the AboutStructuredData component
to accept a fixed lastModified value (e.g., a prop named lastModified or a
build-time constant like COMMIT_DATE/GIT_LAST_MODIFIED) and use that instead of
new Date().toISOString().split('T')[0]; alternatively derive the date at build
time in getStaticProps or from your CMS/git metadata and pass it into
AboutStructuredData so dateModified reflects the actual content change date.

In `@src/components/data-structured/software-application.tsx`:
- Around line 50-54: The publisher object currently creates a separate Person
while author and creator reference `${NEXT_PUBLIC_APP_URL}#person`; update the
publisher entry in the structured data to reuse that same reference (e.g., set
publisher to reference the same "@id": `${NEXT_PUBLIC_APP_URL}#person` or assign
the existing author/creator object) so all three (author, creator, publisher)
consistently point to the same linked entity; locate the publisher object in
software-application.tsx and replace its Person literal with the shared `@id`
reference (keeping appName/NEXT_PUBLIC_APP_URL values).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 80284e57-ff86-4953-9c55-c52719424add

📥 Commits

Reviewing files that changed from the base of the PR and between 86da497 and ab1c21f.

📒 Files selected for processing (10)
  • src/app/(home)/page.tsx
  • src/app/(home)/sections/home-faq.tsx
  • src/app/about/page.tsx
  • src/app/posts/[slug]/page.tsx
  • src/app/posts/layout.tsx
  • src/app/projects/layout.tsx
  • src/components/about-structured-data.tsx
  • src/components/data-structured/article.tsx
  • src/components/data-structured/faq-page.tsx
  • src/components/data-structured/software-application.tsx

@pphatdev pphatdev merged commit ae174e0 into main Mar 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant