✳️ 581+ Pro Blocks, lifetime updates, unlimited projects — Get 50+ fresh blocks every month ✳️ 👇
Grab the deal →

Install astro-seo

Quickly add SEO tags to Astro

by Yucel F. Sahan
6 min read
Updated on

TL;DR

astro-seo is a lightweight component that lives in your <head> and writes every important <title>, <meta> and Open Graph tag for you. Install it with npm install astro-seo, import the <SEO /> component, and pass in page-specific props or site-wide defaults from a layout.

Advanced props cover Twitter cards, canonical URLs, language alternates and even custom link/meta tags.

Once configured, you can validate the output in DevTools or Lighthouse to confirm your Astro site is SEO-ready.

Why bother with SEO in Astro?

Astro ships zero JS by default and renders static HTML that is inherently crawl-friendly, but search engines still rely on well-formed metadata to understand and rank pages.

A missing description or wrong Open Graph image can cost clicks on Google or social media. Automating tags keeps every page consistent and prevents mistakes as your site grows.

What is astro-seo?

  • One-stop component – Wraps dozens of SEO tags in a single, typed component.

  • Next-SEO inspired – Adopts the familiar API from the popular Next.js library.

  • Actively used – >136 k weekly downloads on the Astro Integrations hub.

  • Latest versionv0.8.4 (June 1 2024).

Because it’s a plain component (not an Astro “integration”), installation is as simple as adding a dependency—no astro add step required.

Prerequisites

  • Node 18 + and an existing Astro project (create one with npm create astro@latest).

  • Basic familiarity with layouts and components in Astro.

Step 1 – Install the plugin

# pnpm
pnpm add astro-seo

# npm
npm install astro-seo

# yarn
yarn add astro-seo

Step 2 – Quick start on a single page

---
// src/pages/index.astro
import { SEO } from "astro-seo";
---

<html lang="en">
  <head>
    <SEO
      title="Home – Space Adventures"
      description="Galactic tours from Earth orbit to the Kuiper Belt."
      openGraph={{
        basic: {
          title: "Space Adventures",
          type: "website",
          image: "/og/home.png",
          url: Astro.url.href,   // auto-canonical
        },
      }}
      twitter={{
        site: "@spaceco",
        creator: "@astrodev",
        card: "summary_large_image",
      }}
    />
  </head>
  <body>
    <!-- page content -->
  </body>
</html>

This renders all Open Graph, Twitter and standard meta tags without hand-coding each line.

Step 3 – Centralise metadata in a global layout

Managing props per page gets repetitive. The common pattern is to import <SEO /> once inside src/layouts/BaseLayout.astro and feed it defaults from a JSON or JS module.

---
// src/layouts/BaseLayout.astro
import { SEO } from "astro-seo";
import siteDefaults from "../constants/siteData.json";

const { seo: seoOverrides = {} } = Astro.props;
const seo = { ...siteDefaults.default, ...seoOverrides };
---

<html lang="en">
  <head>
    <SEO {...seo} />
  </head>
  <body>
    <slot />   <!-- page content -->
  </body>
</html>

Then, in any page:

---
import BaseLayout from "../layouts/BaseLayout.astro";
import siteData from "../constants/siteData.json";
const { pages } = siteData;

const seo = pages.about;      // choose slice for /about
---
<BaseLayout seo={seo}>
  <h1>About us</h1>
</BaseLayout>

If a page omits props, siteDefaults.default becomes the graceful fallback.

Step 4 – Unlock advanced options

Prop

Purpose

Example

titleTemplate

Append or prepend brand name automatically

"%s · SpaceCo"

canonical

Override canonical URL

"https://spaceco.com/about"

languageAlternates

Multilingual hreflang tags

[ { href: "/es", hrefLang: "es" } ]

extend.meta / extend.link

Add any custom tag (e.g., favicon, theme-color)

see code below

<SEO
  title="Mars Trips"
  extend={{
    meta: [{ name: "theme-color", content: "#ff0000" }],
    link: [{ rel: "preload", href: "/fonts/space.woff2", as: "font", type: "font/woff2", crossorigin: true }]
  }}
/>

All props are documented in the README and npm page.

Step 5 – Dynamic SEO for collections & CMS data

Because props are plain objects, you can generate them from Markdown front-matter, a headless CMS response or Astro Content Collections:

---
// src/pages/blog/[slug].astro
import { getEntryBySlug } from "astro:content";
import { SEO } from "astro-seo";

const { slug } = Astro.params;
const post = await getEntryBySlug("blog", slug);

const seo = {
  title: post.data.title,
  description: post.data.excerpt,
  openGraph: {
    basic: {
      title: post.data.title,
      type: "article",
      image: post.data.cover,
      url: Astro.url.href
    },
    article: {
      publishedTime: post.data.published,
      tags: post.data.tags
    }
  }
};
---
<SEO {...seo} />
<article>{post.content}</article>

With one component call, every blog post includes correct article metadata.

Step 6 – Validate the output

  • Browser DevTools – View-source or Elements panel to ensure <meta> tags exist.

  • Lighthouse – Run the “SEO” audit; you should see green checks for “Document has a <title> element” and “Meta description”.

  • Social debuggers – Facebook Sharing Debugger & Twitter Card Validator preview how your OG/Twitter tags render.

Common issues & troubleshooting

Issue

Fix

og:url is missing → social previews break

Always pass openGraph.basic.url or rely on Astro.request.url.href (auto-fallback).

Charset meta appears after <title> in HTML 5 validator

Set charset via prop only if you truly need it; the order bug is known (see GitHub issue #91).

Noindex accidentally true

Remember noindex/nofollow default to false; set them explicitly only on staging or thank-you pages.

TypeScript warns about missing fields

Import SEOProps type from "astro-seo" to strongly type helper functions.

Beyond the basics

  1. Structured data – Pair with astro-seo-schema to output JSON-LD for products, articles and breadcrumbs.

  2. Generate a sitemap – Use the official @astrojs/sitemap integration alongside astro-seo.

  3. OG image automation – Combine with astro-og-canvas to create dynamic social images.

Conclusion

astro-seo turns on-page SEO from a chore into a declarative, component-driven workflow. With one install and a handful of props, every page in your Astro project gains consistent metadata, richer social cards and fewer validation errors.

Drop it into your layout today and focus on building great content instead of remembering every last <meta> tag!

Happy coding 🚀

Yucel F. Sahan

Yucel is a digital product creator and content writer with a knack for full-stack development. He loves blending technical know-how with engaging storytelling to build practical, user-friendly solutions. When he's not coding or writing, you'll likely find him exploring new tech trends or getting inspired by nature.