SEO
WollyCMS stores SEO metadata per page — meta title, meta description, OG image, canonical URL, and robots directives. The @wollycms/astro package provides helpers to turn this data into proper HTML meta tags and JSON-LD structured data.
Page SEO fields
Section titled “Page SEO fields”Every page in WollyCMS has these SEO fields (set in the admin UI or via API):
| Field | Purpose |
|---|---|
meta_title | Custom <title> tag (falls back to page title) |
meta_description | Meta description for search results |
og_image | Open Graph image URL |
canonical_url | Canonical URL for duplicate content |
robots | Robots directive (noindex, nofollow, etc.) |
Using getPageSeo
Section titled “Using getPageSeo”import { seoHelpers } from '@wollycms/astro';
const page = await wolly.pages.getBySlug('about');const config = await wolly.config.get();const seo = seoHelpers.getPageSeo(page, config);Returns a SeoMeta object:
interface SeoMeta { title: string; // meta_title || "Page Title | Site Name" description?: string; // meta_description ogImage?: string; // og_image URL canonicalUrl?: string; // canonical_url robots?: string; // robots directive}Rendering in your layout
Section titled “Rendering in your layout”---import { seoHelpers } from '@wollycms/astro';
const { page } = Astro.props;const config = await wolly.config.get();const seo = seoHelpers.getPageSeo(page, config);const siteUrl = import.meta.env.SITE_URL || 'https://example.com';---
<html> <head> <title>{seo.title}</title> {seo.description && <meta name="description" content={seo.description} />} {seo.robots && <meta name="robots" content={seo.robots} />} {seo.canonicalUrl && <link rel="canonical" href={seo.canonicalUrl} />}
<!-- Open Graph --> <meta property="og:title" content={seo.title} /> {seo.description && <meta property="og:description" content={seo.description} />} {seo.ogImage && <meta property="og:image" content={seo.ogImage} />} <meta property="og:url" content={`${siteUrl}/${page.slug}`} /> <meta property="og:type" content="website" /> </head> <body> <slot /> </body></html>Structured data (JSON-LD)
Section titled “Structured data (JSON-LD)”The seoHelpers module provides functions to generate JSON-LD structured data.
Article schema
Section titled “Article schema”For blog posts and articles:
---import { seoHelpers } from '@wollycms/astro';
const jsonLd = seoHelpers.articleJsonLd(page, { siteUrl: 'https://example.com', siteName: 'My Site', authorName: 'Jane Developer',});---
<Fragment set:html={seoHelpers.jsonLdScript(jsonLd)} />WebPage schema
Section titled “WebPage schema”For general pages:
---const jsonLd = seoHelpers.webPageJsonLd(page, { siteUrl: 'https://example.com', siteName: 'My Site',});---
<Fragment set:html={seoHelpers.jsonLdScript(jsonLd)} />Breadcrumb schema
Section titled “Breadcrumb schema”Combine with menu helpers for breadcrumb structured data:
---import { seoHelpers, menuHelpers } from '@wollycms/astro';
const menu = await wolly.menus.get('main-nav');const trail = menuHelpers.getBreadcrumbs(menu.items, Astro.url.pathname);const breadcrumbData = trail.map((item) => ({ title: item.title, url: menuHelpers.getItemHref(item) || '/',}));
const jsonLd = seoHelpers.breadcrumbJsonLd(breadcrumbData, 'https://example.com');---
<Fragment set:html={seoHelpers.jsonLdScript(jsonLd)} />Organization schema
Section titled “Organization schema”For site-wide organization data:
---const config = await wolly.config.get();const jsonLd = seoHelpers.organizationJsonLd(config, { siteUrl: 'https://example.com', logoUrl: 'https://example.com/logo.png',});---
<Fragment set:html={seoHelpers.jsonLdScript(jsonLd)} />Sitemap
Section titled “Sitemap”WollyCMS generates a sitemap automatically at /api/content/sitemap (also available at /sitemap.xml via redirect). It includes all published pages with their lastmod dates.
Pages with robots: "noindex" are excluded from the sitemap.
The sitemap uses the SITE_URL environment variable for absolute URLs:
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>https://example.com/</loc> <lastmod>2025-01-15</lastmod> </url> <url> <loc>https://example.com/about</loc> <lastmod>2025-01-10</lastmod> </url></urlset>OG image generation
Section titled “OG image generation”WollyCMS auto-generates Open Graph images when a page is first published (if no custom OG image is set). The generated image uses the page’s meta title and description.
Auto-generated OG images are served at /api/content/og/:slug.png.
Canonical URLs
Section titled “Canonical URLs”If a page does not have an explicit canonical_url set, you can construct one in your layout:
---const canonicalUrl = seo.canonicalUrl || `${siteUrl}/${page.slug}`;---
<link rel="canonical" href={canonicalUrl} />