Published 2026-10-22 · Data collected 2026-10-20 and 2026-10-21

We checked 3,197 Astro sites for SEO basics

We looked for a sitemap on every site in the Astro showcase, then audited 3,927 pages on the 358 sites with 500 or more URLs in their sitemap. Most of them are in good shape: 72% had none of the serious problems on any page we sampled. The rest tend to miss the same few things, and each one is a small fix in Astro.

32% of the large sites still ship FAQPage or HowTo markup that Google no longer shows

21% have pages with no og:image, so links to them share without a picture

20% reuse the same title or description across pages

20% of all responding showcase sites have no sitemap where crawlers look

6% list pages in their sitemap that tell search engines not to index them

1. A third still ship FAQ markup Google stopped showing

116 of the 358 large sites (32%) have FAQPage or HowTo structured data on at least one sampled page: FAQPage on 114, HowTo on 7. That is 611 of 3,927 pages (16%), and 48 of the 356 showcase entry pages.

Google limited FAQ rich results to government and health sites in 2023, removed HowTo results the same year, and stopped showing FAQ results entirely on 7 May 2026. The markup does no harm: there's no penalty, and other search engines may still read it. It just no longer earns anything in Google, so it's not worth adding to new pages or maintaining by hand.

2. One in five has pages that share as a bare link

74 of 358 sites (21%) have at least one sampled page without an og:image, and 33 (9%) have none on any page we sampled. Across all pages it's 520 of 3,927 (13%). Without one, LinkedIn, Facebook and Slack show a card without a picture, or just the URL. 159 pages had no Open Graph tags at all.

The homepage usually isn't the problem: 14% of showcase entry pages lacked an og:image. It's the blog post or docs page someone actually shares, rendered by a layout that only sets the image when a page passes one.

3. Duplicate titles and descriptions

We sampled about 11 pages per site. On 69 of the 353 sites with two or more audited pages (20%), at least two of those pages had exactly the same title or meta description: 64 sites repeated a description, 38 a title. With only 11 pages sampled per site, the real number is higher. 38 sites (11%) also had pages with no meta description at all (198 pages, 5%).

The usual cause is a layout with a default description that every page inherits.

4. Sitemaps: missing, or hidden behind a broken robots.txt line

Of the 2,831 showcase sites that responded, 554 (20%) had no sitemap at the URL in their robots.txt, at /sitemap-index.xml or at /sitemap.xml. For a five-page portfolio that hardly matters; for a site with hundreds of pages it does.

The odder group: 81 sites have a Sitemap: line in robots.txt that leads nowhere, and 57 of them have a working sitemap at the default path all along. The line points at a relative path (Google needs the full URL), at a placeholder domain like example.com left over from a template, or at an old host.

Sitemap URLs at sizingSites (of 3,197)
No sitemap found (incl. 366 sites that didn't load)978 (31%)
Empty sitemap (0 URLs)18 (1%)
1–49995 (31%)
50–499840 (26%)
500–4,999280 (9%)
5,000 or more86 (3%)

5. Noindex pages listed in the sitemap

20 of the 358 sites (6%) list pages in their sitemap that carry noindex: 57 pages in all. They're mostly pages people noindex on purpose, such as tag archives, pagination, embedded demos and translated variants. Noindexing them is fine. Listing them in the sitemap sends the opposite signal: a sitemap is meant to list the pages you want in search. @astrojs/sitemap includes every page unless you filter some out.

Everything we measured

CheckPages (of 3,927)Sites with at least one (of 358)
FAQPage or HowTo JSON-LD611 (16%)116 (32%)
No og:image520 (13%)74 (21%)
No meta description198 (5%)38 (11%)
No canonical URL245 (6%)36 (10%)
No H1248 (6%)63 (18%)
noindex (while listed in the sitemap)57 (1%)20 (6%)
No JSON-LD at all1,003 (26%)
No twitter:card485 (12%)
Images without alt214 (5%)
Title outside 30–60 characters1,756 (45%)
Description outside 70–155 characters1,661 (42%)
No <title>40 (1%)
No lang on <html>49 (1%)

The average page scored 87 out of 100 on our free checker's ten checks, mostly losing points on title and description length. 257 of the 358 sites (72%) had no missing og:image, missing description or noindex page anywhere in the sample.

How to fix it in Astro

A default og:image and a description every page must set

Put the tags in one layout, give the image a fallback, and make description a required prop so astro check flags any page that forgets it. Set site in astro.config.mjs so the URLs come out absolute: Open Graph needs absolute URLs.

---
// src/layouts/BaseLayout.astro
interface Props {
  title: string;
  description: string;
  image?: string;
}
const { title, description, image = '/og-default.png' } = Astro.props;
const canonical = new URL(Astro.url.pathname, Astro.site);
const ogImage = new URL(image, Astro.site);
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>{title}</title>
    <meta name="description" content={description} />
    <link rel="canonical" href={canonical} />
    <meta property="og:title" content={title} />
    <meta property="og:description" content={description} />
    <meta property="og:image" content={ogImage} />
    <meta name="twitter:card" content="summary_large_image" />
  </head>
  <body>
    <slot />
  </body>
</html>

Put a 1200×630 image at public/og-default.png. Pages pass their own with <BaseLayout title="…" description="…" image="/og/post.png">. For content collections, make description required in the collection's schema too, so a post without one fails the build instead of inheriting a default.

A sitemap that robots.txt points to correctly

npx astro add sitemap
// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',
  integrations: [
    sitemap({
      // Leave out pages you mark noindex, such as tag archives.
      filter: (page) => !page.includes('/tags/'),
    }),
  ],
});

The build writes sitemap-index.xml and sitemap-0.xml. Generate robots.txt from the same site value instead of hard-coding a URL, so it can't drift to a relative path or a template's placeholder domain:

// src/pages/robots.txt.ts
import type { APIRoute } from 'astro';

const getRobotsTxt = (sitemapURL: URL) => `User-agent: *
Allow: /

Sitemap: ${sitemapURL.href}
`;

export const GET: APIRoute = ({ site }) => {
  const sitemapURL = new URL('sitemap-index.xml', site);
  return new Response(getRobotsTxt(sitemapURL));
};

Delete public/robots.txt if you have one, so there is only one source. This follows the @astrojs/sitemap guide.

FAQ markup

Nothing breaks if you leave it. If you maintain it by hand, it's safe to stop adding it to new pages.

If you'd rather not write descriptions and Open Graph tags for every page yourself, Headlark can write them after astro build. To see where your own site stands, run any page through the free SEO checker.

How we did it