Skip to content

Enhance SEO metadata and add structured data for better discoverability#140

Open
charuljain02 wants to merge 1 commit intoAOSSIE-Org:mainfrom
charuljain02:seo-structured-data-improvement
Open

Enhance SEO metadata and add structured data for better discoverability#140
charuljain02 wants to merge 1 commit intoAOSSIE-Org:mainfrom
charuljain02:seo-structured-data-improvement

Conversation

@charuljain02
Copy link

@charuljain02 charuljain02 commented Feb 21, 2026

Title

Enhance SEO Metadata and Structured Data for Better Discoverability

📌 Description

This PR improves the application's metadata configuration to enhance search engine discoverability, structured indexing, and social media preview rendering.
The update extends the existing Next.js metadata configuration without modifying any UI or business logic.

🚀 Changes Made

  • Extended metadata using Next.js Metadata API
  • Added OpenGraph metadata for better social sharing previews
  • Added Twitter card metadata configuration
  • Injected JSON-LD structured data (SoftwareApplication schema)
  • Ensured no impact on existing functionality

🎯 Impact

  • Improved SEO clarity
  • Enhanced social media link previews
  • Better structured data recognition by search engines
  • No UI or functional changes introduced

🔗 Related Issue

Closes #139

✅ Checklist

  • Code follows project guidelines
  • No breaking changes introduced
  • Changes tested locally
  • Issue linked properly

Looking forward to feedback from the maintainers 🙌

Summary by CodeRabbit

  • Chores
    • Added comprehensive metadata for improved search engine visibility, including keywords and structured schema data.
    • Enhanced social media sharing with OpenGraph and Twitter card metadata for better application previews across platforms.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 21, 2026

📝 Walkthrough

Walkthrough

Extended the Next.js app's public metadata configuration with OpenGraph and Twitter card metadata, added SEO keywords, and injected JSON-LD structured data describing the software application for improved search engine and social platform discoverability.

Changes

Cohort / File(s) Summary
SEO Metadata & Structured Data
frontend/app/layout.tsx
Enhanced public metadata object with extended description, keywords array, OpenGraph properties (title, description, URL, siteName, type), and Twitter card metadata. Added inline JSON-LD script block rendering SoftwareApplication schema with context, type, name, category, description, OS, and URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

🐰 A hop, skip, and metadata jump away,
Our web app shines in searches' light today!
With OpenGraph, Twitter cards so bright,
JSON-LD whispers, making ranking right.
Now rabbits and algorithms alike can see,
What makes Perspective quite spectacularly free! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main changes: enhanced SEO metadata and added structured data, which are the core focus of the changeset.
Linked Issues check ✅ Passed All five coding objectives from issue #139 are met: metadata extended, OpenGraph added, Twitter cards added, JSON-LD structured data injected, and no functional impact.
Out of Scope Changes check ✅ Passed All changes in the PR are directly aligned with issue #139 requirements; no out-of-scope modifications are present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/app/layout.tsx`:
- Around line 20-33: The openGraph and twitter metadata objects (openGraph and
twitter) are missing images while using the "summary_large_image" card type;
either add an images array to openGraph and a twitter.images or twitter.image
entry with a public image URL (and alt text where supported) to provide the
large thumbnail, or change twitter.card from "summary_large_image" to "summary"
if you cannot supply an image yet; update the openGraph.images and
twitter.image(s) references in layout.tsx accordingly so social previews render
correctly.
- Around line 56-70: Update the JSON-LD object passed to
dangerouslySetInnerHTML: change applicationCategory from "AIApplication" to a
Google-supported value such as "UtilitiesApplication" (or
"DeveloperApplication"), and add the required rich result fields so Google can
surface a software rich result — e.g. include an "offers" object with "price": 0
and "priceCurrency": "USD" and add either an "aggregateRating" object (with
"ratingValue" and "reviewCount") or a "review" array with at least one review;
modify the literal inside the JSON.stringify in the <script
type="application/ld+json"> block so these properties are present and populated
appropriately.

Comment on lines +20 to +33
openGraph: {
title: "Perspective - AI-Powered Bias Detection",
description:
"Analyze content for bias and generate alternative AI-driven perspectives.",
url: "https://perspective-aossie.vercel.app/",
siteName: "Perspective",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Perspective - AI-Powered Bias Detection",
description:
"AI-powered tool to analyze bias and generate alternative perspectives.",
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

summary_large_image card type without an images property will render poorly on social platforms.

Both openGraph and twitter metadata are missing images. The summary_large_image card type features a large, full-width prominent image alongside a tweet and is designed to give the reader a rich photo experience. Without providing twitter:image, "Twitter says that the image should be unique to the page, but if you don't include an image, the card they produce has a silly-looking icon on it (of a scroll or document)." Similarly, OG shares on LinkedIn, Slack, and other platforms will display no visual thumbnail.

The suggested minimum properties for the Summary Card with Large Image include title, description, and image.

Either add images arrays to both openGraph and twitter, or downgrade the Twitter card to "summary" if no image is available yet.

🖼️ Proposed fix — add images or downgrade Twitter card type
  openGraph: {
    title: "Perspective - AI-Powered Bias Detection",
    description:
      "Analyze content for bias and generate alternative AI-driven perspectives.",
    url: "https://perspective-aossie.vercel.app/",
    siteName: "Perspective",
    type: "website",
+   images: [
+     {
+       url: "https://perspective-aossie.vercel.app/og-image.png",
+       width: 1200,
+       height: 630,
+       alt: "Perspective - AI-Powered Bias Detection",
+     },
+   ],
  },
  twitter: {
-   card: "summary_large_image",
+   card: "summary",   // upgrade to "summary_large_image" once a twitter:image is available
    title: "Perspective - AI-Powered Bias Detection",
    description:
      "AI-powered tool to analyze bias and generate alternative perspectives.",
  },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
openGraph: {
title: "Perspective - AI-Powered Bias Detection",
description:
"Analyze content for bias and generate alternative AI-driven perspectives.",
url: "https://perspective-aossie.vercel.app/",
siteName: "Perspective",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Perspective - AI-Powered Bias Detection",
description:
"AI-powered tool to analyze bias and generate alternative perspectives.",
},
openGraph: {
title: "Perspective - AI-Powered Bias Detection",
description:
"Analyze content for bias and generate alternative AI-driven perspectives.",
url: "https://perspective-aossie.vercel.app/",
siteName: "Perspective",
type: "website",
images: [
{
url: "https://perspective-aossie.vercel.app/og-image.png",
width: 1200,
height: 630,
alt: "Perspective - AI-Powered Bias Detection",
},
],
},
twitter: {
card: "summary",
title: "Perspective - AI-Powered Bias Detection",
description:
"AI-powered tool to analyze bias and generate alternative perspectives.",
},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/app/layout.tsx` around lines 20 - 33, The openGraph and twitter
metadata objects (openGraph and twitter) are missing images while using the
"summary_large_image" card type; either add an images array to openGraph and a
twitter.images or twitter.image entry with a public image URL (and alt text
where supported) to provide the large thumbnail, or change twitter.card from
"summary_large_image" to "summary" if you cannot supply an image yet; update the
openGraph.images and twitter.image(s) references in layout.tsx accordingly so
social previews render correctly.

Comment on lines +56 to +70
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "SoftwareApplication",
name: "Perspective",
applicationCategory: "AIApplication",
description:
"Perspective is an AI-powered tool that detects bias in text and generates alternative perspectives.",
operatingSystem: "Web",
url: "https://perspective-aossie.vercel.app/",
}),
}}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's confirm the file exists and view the actual code at lines 56-70
cat -n frontend/app/layout.tsx | sed -n '56,70p'

Repository: AOSSIE-Org/Perspective

Length of output: 793


🌐 Web query:

schema.org SoftwareApplication applicationCategory valid values

💡 Result:

SoftwareApplication.applicationCategory in schema.org does not have a fixed set of “valid values”. The property’s expected type is Text or URL, and schema.org only describes it as “Type of software application” (example: “Game, Multimedia”). So any reasonable free-text label (or a URL pointing to a category in some taxonomy you control/use) is valid from a schema.org perspective. [1]

If you care specifically about Google Software App rich results, Google says the value “must be a supported app type” and provides this supported list: GameApplication, SocialNetworkingApplication, TravelApplication, ShoppingApplication, SportsApplication, LifestyleApplication, BusinessApplication, DesignApplication, DeveloperApplication, DriverApplication, EducationalApplication, HealthApplication, FinanceApplication, SecurityApplication, BrowserApplication, CommunicationApplication, DesktopEnhancementApplication, EntertainmentApplication, MultimediaApplication, HomeApplication, UtilitiesApplication, ReferenceApplication. [2]

Sources:
[1] Schema.org – SoftwareApplication / applicationCategory definition: expected type Text or URL
[2] Google Search Central – Software app structured data (SoftwareApplication), supported applicationCategory values


🌐 Web query:

Google Rich Results SoftwareApplication requirements schema.org

💡 Result:

Google’s Software app rich result is based on Schema.org’s SoftwareApplication (and optionally MobileApplication / WebApplication). To be eligible, Google says your structured data must include:

Required (Google rich result eligibility)

  • @type: SoftwareApplication (Schema.org type) [2]
  • name [1]
  • offers.price (set to 0 if free) [1]
  • One of: aggregateRating or review (rating/review is required) [1]

Recommended (improves/clarifies results)

  • offers.priceCurrency when offers.price > 0 [1]
  • applicationCategory (must be one of Google’s supported categories) [1]
  • operatingSystem [1]

Notes

  • Google supports MobileApplication and WebApplication as subtypes; and if you use VideoGame, Google recommends co-typing it with another supported type (for eligibility). [1]

Sources: Google Search Central “Software app (SoftwareApplication) structured data” [1], Schema.org SoftwareApplication definition [2].


applicationCategory: "AIApplication" is not a Google-supported value; schema may not qualify for Google Rich Results.

dangerouslySetInnerHTML (Line 58): Safe here. The injected content is a static JSON.stringify() of a hardcoded literal with no user input. This is the recommended Next.js pattern for JSON-LD structured data.

applicationCategory: "AIApplication" (Line 63): Not a recognized value in Google's SoftwareApplication supported types. Google's supported categories include: GameApplication, BusinessApplication, DeveloperApplication, EducationApplication, UtilitiesApplication, ReferenceApplication, and others. "AIApplication" is absent. Use "UtilitiesApplication" or "DeveloperApplication" instead.

Google Rich Results eligibility: To qualify for Google's software app rich results, the schema must include offers.price (set to 0 if free) and either aggregateRating or review. The current implementation provides context to crawlers but won't display as a rich result. Add these properties for eligibility.

✏️ Suggested fix
-   applicationCategory: "AIApplication",
+   applicationCategory: "UtilitiesApplication",

Also add required properties for Google Rich Results:

  offers: {
+   price: "0",
+   priceCurrency: "USD"
  },

And one of:

+   aggregateRating: {
+     "@type": "AggregateRating",
+     ratingValue: "4.5",
+     ratingCount: "10"
+   }
🧰 Tools
🪛 ast-grep (0.40.5)

[warning] 57-57: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

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

In `@frontend/app/layout.tsx` around lines 56 - 70, Update the JSON-LD object
passed to dangerouslySetInnerHTML: change applicationCategory from
"AIApplication" to a Google-supported value such as "UtilitiesApplication" (or
"DeveloperApplication"), and add the required rich result fields so Google can
surface a software rich result — e.g. include an "offers" object with "price": 0
and "priceCurrency": "USD" and add either an "aggregateRating" object (with
"ratingValue" and "reviewCount") or a "review" array with at least one review;
modify the literal inside the JSON.stringify in the <script
type="application/ld+json"> block so these properties are present and populated
appropriately.

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.

Enhance SEO Metadata and Structured Data for Better Discoverability

1 participant