Peekly

Open Graph tags in Astro

Astro prints the meta tags that are in the layout head. Pass the title, description, and image in from the page, or read them from Markdown frontmatter. Build the site, then paste the public URL into the checker above.

Free. No signup. Public pages only.

Add the tags

  • A head component in the layout. Astro's config docs say the config file is for the build, and common SEO metadata goes in the page head as ordinary meta tags. The pattern they show is a small Astro component, included from a shared layout, so every page gets the same tags. Set site in astro.config.mjs to the deployed origin, including https. Astro.site is that value. new URL(Astro.url.pathname, Astro.site) is og:url, and new URL("/og.png", Astro.site) is og:image. An absolute image URL is kept as written. A root path is joined to site. When site is missing, Astro.site is undefined and that constructor throws, and @astrojs/sitemap will not generate. og: tags use the property attribute. twitter:card uses name. summary_large_image is the large card on X. The How to Add Open Graph Tags page is those properties and the image URL rules. The Next.js Open Graph page is the same fields as a metadata export.
    ---
    const { title, description, image = "/og.png" } = Astro.props;
    const canonical = new URL(Astro.url.pathname, Astro.site);
    const ogImage = new URL(image, Astro.site);
    ---
    <meta property="og:title" content={title} />
    <meta property="og:description" content={description} />
    <meta property="og:url" content={canonical} />
    <meta property="og:type" content="website" />
    <meta property="og:image" content={ogImage} />
    <meta property="og:image:width" content="1200" />
    <meta property="og:image:height" content="630" />
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:image" content={ogImage} />
  • Markdown frontmatter. A Markdown file in src/pages/ can set layout to a relative path. That key is the one Astro treats as special, and only for files in src/pages/. Every other frontmatter key arrives on the layout as Astro.props.frontmatter. title and description there are the share title and summary. image should be a root path such as /og.png, or an absolute https URL. Content collections do not treat layout as special. Render a collection entry from an .astro page and pass the entry data into the layout as ordinary props. When a Markdown file uses the layout key, Astro stops inserting the charset for you, so the layout head has to include it. The slot is the rendered Markdown. An image imported from src/ exposes src, width, and height. Use that width and height for og:image:width and og:image:height when the file is not 1200×630. The Open Graph Image Size page is that 1200×630 baseline.
    src/pages/posts/post.md
    ---
    layout: ../../layouts/Post.astro
    title: Post title
    description: One or two sentences.
    image: /og.png
    ---
    
    src/layouts/Post.astro
    ---
    import Head from "../components/Head.astro";
    const { frontmatter } = Astro.props;
    ---
    <html>
      <head>
        <meta charset="utf-8" />
        <Head
          title={frontmatter.title}
          description={frontmatter.description}
          image={frontmatter.image}
        />
      </head>
      <body>
        <slot />
      </body>
    </html>
  • The sitemap integration. @astrojs/sitemap writes sitemap-index.xml and sitemap-0.xml when you build. It needs site, and the origin has to start with http:// or https://. It includes static routes and pages from getStaticPaths(). The integration docs say it cannot add entries for dynamic routes rendered on demand. filter, customPages, and serialize change that XML. They do not change the share card. A link rel="sitemap" in the head points crawlers at the index file. It is a discovery hint for the sitemap, and it is separate from og:title and og:image. Install it with npx astro add sitemap, or add the package and the integrations entry yourself. The Open Graph tags still come from the layout component above. The Open Graph Checker reads those meta tags from the page HTML.
    import { defineConfig } from "astro/config";
    import sitemap from "@astrojs/sitemap";
    
    export default defineConfig({
      site: "https://example.com",
      integrations: [sitemap()],
    });
  • What a crawler receives. The default Astro output is static HTML, and the meta tags in the layout are in that file. A server-rendered route runs the same template for the request, and the tags are in that response. A script inside a client island that writes a meta tag after load is absent from the HTML a crawler fetched. View source, or curl the URL, and read the head. Paste the public URL, not a localhost address. Peekly grades og:title, og:description, og:image, and twitter:card, and it downloads the image. The Twitter Card Validator is the card summary_large_image selects. The Nuxt Open Graph, Remix Open Graph, and SvelteKit Open Graph pages are the same tags in those frameworks.

Tags covered: og:title · og:description · og:image · og:url · og:type · twitter:card · twitter:image

More checkers

Twitter Card ValidatorOpen Graph CheckerLinkedIn Link Preview CheckerDiscord Embed PreviewWhatsApp Link Preview CheckerSlack Link Preview CheckeriMessage Link Preview CheckerFacebook Link Preview CheckerOpen Graph Image SizeTelegram Link Preview CheckerReddit Link Preview CheckerNext.js Open GraphRefresh a Link Preview CacheBluesky Link Preview CheckerMastodon Link Preview CheckerMicrosoft Teams Link Preview CheckerFix a Broken Open Graph PreviewInstagram Link Preview CheckerPinterest Link Preview CheckerTikTok Link Preview CheckerYouTube Link Preview CheckerThreads Link Preview CheckerSnapchat Link Preview CheckerHow to Add Open Graph TagsOpen Graph Image Not UpdatingDiscord Link PreviewX (Twitter) Link PreviewWordPress Open GraphShopify Open GraphNuxt Open GraphRemix Open GraphSvelteKit Open GraphAll platforms

What each platform reads

  • X / Twittertwitter:card, twitter:* → og:* fallback1200×630 (min 300×157), < 5 MB
  • Facebookog:title, og:description, og:image1200×630, 1.91:1
  • LinkedInog:title, og:image (og: only)1200×627, 1.91:1
  • Discordog:site_name, og:*, theme-color, twitter:cardLarge image needs summary_large_image
  • Slackog:site_name, og:title, og:description, og:image1200×630
  • WhatsAppog:title, og:description, og:imageKeep < 300 KB

Guidance based on each platform's public documentation and observed behavior. Platforms change their rules without notice.

FAQ

+Is Peekly free?

Yes. Checking a single URL is free forever — no signup and no limit on one-off checks. Batch watching and monitoring may arrive later as a paid Pro plan; the free single-URL tool stays.

+Why does my link show no image when I share it?

Usually one of four things: there's no og:image tag, the image URL is relative instead of absolute, the image is behind a login, firewall or bot block, or the file is too big or in an unsupported format like SVG. Peekly checks all four and tells you which one it is.

+What size should my og:image be?

1200×630 pixels (a 1.91:1 ratio) as a PNG or JPG under about 300 KB. That size works for large cards on X, Facebook, LinkedIn, Discord, Slack and WhatsApp.

+Do I need twitter: tags if I already have Open Graph tags?

X reads og:title, og:description and og:image as fallbacks, but you still need twitter:card set to summary_large_image if you want the big image card. Without it, X shows a small thumbnail.

+I fixed my tags but the old preview still shows. Why?

Platforms cache link previews, sometimes for days. Facebook and LinkedIn let you force a refresh with their own debugging tools. On X, Slack and Discord the cache usually expires on its own, or you can add a query string such as ?v=2 to the URL.

+Do you store the pages I check?

No. We fetch the page once to read its <head>, show you the result, and don't save the page or the result. We only fetch public http(s) URLs, and private or internal addresses are blocked.

+Are the previews pixel-perfect?

They're close approximations of each platform's current card layout, built from the same tags the platforms read. Platforms change their designs from time to time, so treat them as a very good guide rather than a screenshot.

$9

One time

A written fix for the batch.

Up to 25 URLs. We check og:image, Twitter cards, size, redirects, and cache, then send copy-paste meta tags within 48 hours. The free single-URL check stays free.

Get the fix report — $9