Summary
The homepage serves og:type=article. The homepage should declare og:type=website for correct entity/social typing, which also aligns with the WebSite schema entity already emitted on the page.
Evidence
- Live
https://aspire.dev/ <head> contains <meta property="og:type" content="article"> (emitted by Starlight's DefaultHead).
- The site already computes the correct value:
resolveOgType() in src/frontend/src/utils/page-metadata.ts (lines ~156–178) returns 'website' for the home page and any template: splash page, and getOgMetadata() surfaces it as type.
Root cause / where the change goes
getOgMetadata().type is computed but never emitted, so Starlight's hardcoded og:type=article wins. The head-optimization middleware only upserts og:title and og:description:
src/frontend/src/route-data-middleware.ts — optimizeOpenGraphHead() (lines ~116–128) calls upsertMetaEntry(head, 'property', 'og:title', og.ogTitle) and ... 'og:description', og.description), but not og:type.
Fix by upserting the type in the same place:
upsertMetaEntry(head, 'property', 'og:type', og.type);
upsertMetaEntry replaces the existing head entry in place (matching on the property attribute), so no duplicate og:type tag is produced. This keeps the middleware as the single source of truth for OG head tags. (Emitting it directly in components/starlight/Head.astro would instead risk a duplicate tag alongside Starlight's default.)
Done when
- Re-scrape / social debugger shows
og:type=website on /, while docs/article pages still show article.
- Optionally add a unit test asserting the
og:type upsert for a home/splash route vs. an article route.
Source: SEO audit of https://aspire.dev/ (2026-07-29). Priority: Medium.
Summary
The homepage serves
og:type=article. The homepage should declareog:type=websitefor correct entity/social typing, which also aligns with theWebSiteschema entity already emitted on the page.Evidence
https://aspire.dev/<head>contains<meta property="og:type" content="article">(emitted by Starlight'sDefaultHead).resolveOgType()insrc/frontend/src/utils/page-metadata.ts(lines ~156–178) returns'website'for the home page and anytemplate: splashpage, andgetOgMetadata()surfaces it astype.Root cause / where the change goes
getOgMetadata().typeis computed but never emitted, so Starlight's hardcodedog:type=articlewins. The head-optimization middleware only upsertsog:titleandog:description:src/frontend/src/route-data-middleware.ts—optimizeOpenGraphHead()(lines ~116–128) callsupsertMetaEntry(head, 'property', 'og:title', og.ogTitle)and... 'og:description', og.description), but notog:type.Fix by upserting the type in the same place:
upsertMetaEntryreplaces the existing head entry in place (matching on thepropertyattribute), so no duplicateog:typetag is produced. This keeps the middleware as the single source of truth for OG head tags. (Emitting it directly incomponents/starlight/Head.astrowould instead risk a duplicate tag alongside Starlight's default.)Done when
og:type=websiteon/, while docs/article pages still showarticle.og:typeupsert for a home/splash route vs. an article route.Source: SEO audit of
https://aspire.dev/(2026-07-29). Priority: Medium.