Enhance SEO metadata and add structured data for better discoverability#140
Enhance SEO metadata and add structured data for better discoverability#140charuljain02 wants to merge 1 commit intoAOSSIE-Org:mainfrom
Conversation
📝 WalkthroughWalkthroughExtended 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
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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.
| 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.", | ||
| }, |
There was a problem hiding this comment.
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.
| 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.
| <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/", | ||
| }), | ||
| }} | ||
| /> |
There was a problem hiding this comment.
🧩 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 to0if free) [1]- One of:
aggregateRatingorreview(rating/review is required) [1]
Recommended (improves/clarifies results)
offers.priceCurrencywhenoffers.price > 0[1]applicationCategory(must be one of Google’s supported categories) [1]operatingSystem[1]
Notes
- Google supports
MobileApplicationandWebApplicationas subtypes; and if you useVideoGame, 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.
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
SoftwareApplicationschema)🎯 Impact
🔗 Related Issue
Closes #139
✅ Checklist
Looking forward to feedback from the maintainers 🙌
Summary by CodeRabbit