@jdevalk/astro-seo-graph 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -27,12 +27,14 @@ Two packages:
27
27
  ## Contents
28
28
 
29
29
  **Schema core** — concepts and builders for the JSON-LD graph:
30
+
30
31
  - [Architecture](#architecture)
31
32
  - [Installation](#installation)
32
33
  - [The @id system](#the-id-system)
33
34
  - [Piece builders reference](#piece-builders-reference)
34
35
 
35
36
  **Recipes and patterns** — how to model real sites:
37
+
36
38
  - [Site type recipes](#site-type-recipes)
37
39
  - [Trust and credibility signals](#trust-and-credibility-signals)
38
40
  - [Choosing the right Article subtype](#choosing-the-right-article-subtype)
@@ -43,6 +45,7 @@ Two packages:
43
45
  - [Reference implementations](#reference-implementations)
44
46
 
45
47
  **Astro integration** — runtime component and build-time checks:
48
+
46
49
  - [Astro integration guide](#astro-integration-guide) — the `<Seo>` component, hreflang, schema endpoints
47
50
  - [Build-time integration](#build-time-integration) — `seoGraph()` hook, H1 validation, metadata uniqueness, IndexNow, `llms.txt`
48
51
  - [Complete integration example](#complete-integration-example)
@@ -2573,18 +2576,24 @@ const blog = defineCollection({
2573
2576
  }
2574
2577
  ```
2575
2578
 
2576
- ### `buildAstroSeoProps`
2579
+ ### `buildSeoContext`
2577
2580
 
2578
- Pure-TS function that powers `<Seo>` internally. Use when you want to feed a
2579
- different head component:
2581
+ Pure-TS function that powers `<Seo>` internally. Returns a flat,
2582
+ render-ready normalization of `SeoProps` (resolved title, canonical, OG
2583
+ fields, hreflang entries, robots directives, twitter overrides). Use when
2584
+ you want to render the head yourself:
2580
2585
 
2581
2586
  ```ts
2582
- import { buildAstroSeoProps } from '@jdevalk/astro-seo-graph';
2587
+ import { buildSeoContext } from '@jdevalk/astro-seo-graph';
2583
2588
 
2584
- const astroSeoProps = buildAstroSeoProps(mySeoProps, Astro.url.href);
2585
- // Pass to astro-seo's <SEO> or any custom head component
2589
+ const ctx = buildSeoContext(mySeoProps, Astro.url.href);
2590
+ // ctx.title, ctx.canonical, ctx.og.*, ctx.twitter, ctx.hreflangs, ...
2586
2591
  ```
2587
2592
 
2593
+ The companion constant `ROBOTS_EXTRAS` exposes the
2594
+ `max-snippet:-1, max-image-preview:large, max-video-preview:-1`
2595
+ directives that `<Seo>` always appends to the robots tag.
2596
+
2588
2597
  ### `buildAlternateLinks`
2589
2598
 
2590
2599
  Pure helper for hreflang link generation. No Astro runtime needed — safe
@@ -2634,12 +2643,12 @@ export default defineConfig({
2634
2643
 
2635
2644
  ### Options
2636
2645
 
2637
- | Option | Default | Purpose |
2638
- | ------------------------ | ------- | -------------------------------------------------------------------------- |
2639
- | `validateH1` | `true` | Warn when a page has zero or >1 `<h1>` elements. |
2640
- | `validateUniqueMetadata` | `true` | Warn when two pages share the same `<title>` or meta description. |
2641
- | `indexNow` | — | Submit built URLs to IndexNow. Omit to disable. |
2642
- | `llmsTxt` | — | Generate `llms.txt` at the root of the build output. Omit to disable. |
2646
+ | Option | Default | Purpose |
2647
+ | ------------------------ | ------- | --------------------------------------------------------------------- |
2648
+ | `validateH1` | `true` | Warn when a page has zero or >1 `<h1>` elements. |
2649
+ | `validateUniqueMetadata` | `true` | Warn when two pages share the same `<title>` or meta description. |
2650
+ | `indexNow` | — | Submit built URLs to IndexNow. Omit to disable. |
2651
+ | `llmsTxt` | — | Generate `llms.txt` at the root of the build output. Omit to disable. |
2643
2652
 
2644
2653
  ### H1 and metadata validation
2645
2654
 
@@ -2652,7 +2661,11 @@ can only be spotted across the whole corpus.
2652
2661
  Both extractors are exported for reuse:
2653
2662
 
2654
2663
  ```ts
2655
- import { countH1s, extractTitle, extractMetaDescription } from '@jdevalk/astro-seo-graph/integration';
2664
+ import {
2665
+ countH1s,
2666
+ extractTitle,
2667
+ extractMetaDescription,
2668
+ } from '@jdevalk/astro-seo-graph/integration';
2656
2669
  ```
2657
2670
 
2658
2671
  ### IndexNow submission
@@ -2678,7 +2691,7 @@ their trailing-slash form.
2678
2691
  the key is reachable in production get rejected (HTTP 403) and the key
2679
2692
  is treated as invalid — you'll have to rotate it. Serve the key via
2680
2693
  `createIndexNowKeyRoute` (see below), deploy, confirm the `.txt` loads
2681
- over HTTPS, *then* enable `indexNow` in the integration.
2694
+ over HTTPS, _then_ enable `indexNow` in the integration.
2682
2695
 
2683
2696
  ```ts
2684
2697
  // src/pages/[your-key-here].txt.ts
@@ -3262,7 +3275,8 @@ seo-graph/
3262
3275
  │ ├── alternates.ts # buildAlternateLinks
3263
3276
  │ ├── content.ts # seoSchema, imageSchema
3264
3277
  │ └── components/
3265
- └── seo-props.ts # buildAstroSeoProps
3278
+ ├── seo-props.ts # SeoProps interface
3279
+ │ └── seo-context.ts # buildSeoContext
3266
3280
  ├── AGENTS.md # This file
3267
3281
  ├── README.md # Project overview
3268
3282
  └── pnpm-workspace.yaml
package/README.md CHANGED
@@ -11,6 +11,11 @@ component, and Zod helpers for content schemas.
11
11
  For detailed usage — including all builder signatures, site-type recipes, and
12
12
  schema.org best practices — see [AGENTS.md](https://github.com/jdevalk/seo-graph/blob/main/AGENTS.md).
13
13
 
14
+ > **Using an AI coding assistant?** The [`astro-seo` skill](https://github.com/jdevalk/skills/tree/main/astro-seo)
15
+ > audits and improves the full SEO setup of an Astro site — technical
16
+ > foundation, structured data, sitemaps, IndexNow, agent discovery, and
17
+ > more — and produces drop-in code routed through this package.
18
+
14
19
  ## What you get
15
20
 
16
21
  | API | Purpose |
@@ -20,11 +25,11 @@ schema.org best practices — see [AGENTS.md](https://github.com/jdevalk/seo-gra
20
25
  | **`createSchemaMap`** | Factory returning an `APIRoute` handler that emits a sitemap-style XML listing of your site's schema endpoints — the discovery point for agent crawlers. |
21
26
  | **`aggregate`** | Shared engine behind the endpoint factories. Walks a list of entries, runs a caller-supplied mapper, deduplicates by `@id`. |
22
27
  | **`seoSchema`, `imageSchema`** | Zod schemas for the `seo` and `image` fields on content collections. Import them into `src/content.config.ts`. |
23
- | **`buildAstroSeoProps`** | Pure-TS logic that powers `<Seo>` — exported for users who want to feed a different head component. |
28
+ | **`buildSeoContext`** | Pure-TS logic that powers `<Seo>` — returns a flat, normalized projection of `SeoProps` (resolved title, canonical, OG fields, hreflang entries, robots directives). Exported for users who want to render the head themselves. |
24
29
  | **`buildAlternateLinks`** | Pure helper that turns a `{ hreflang, href }` entry list into normalized `<link rel="alternate">` tags plus an `x-default`. Used internally by `<Seo>`'s `alternates` prop, and exported for non-Astro callers (e.g. CMS plugins feeding their own metadata pipelines). |
25
30
  | **`breadcrumbsFromUrl`** | Derives a breadcrumb trail from an Astro URL. Splits path segments, supports custom display names and segment skipping. Returns `BreadcrumbItem[]` ready to pass to `buildBreadcrumbList`. |
26
31
  | **`<FuzzyRedirect>`** | Drop-in 404 component. Fetches your sitemap, fuzzy-matches the current URL against known paths, and suggests or auto-redirects to the closest match. |
27
- | **`createIndexNowKeyRoute`** | Factory returning an `APIRoute` that serves the IndexNow key-verification file at `/<key>.txt`. Pair with the `indexNow` option on the integration to auto-submit built URLs on `astro:build:done`. |
32
+ | **`createIndexNowKeyRoute`** | Factory returning an `APIRoute` that serves the IndexNow key-verification file at `/<key>.txt`. Pair with the `indexNow` option on the integration to auto-submit built URLs on `astro:build:done`. |
28
33
 
29
34
  ## Installation
30
35
 
@@ -366,11 +371,11 @@ export default defineConfig({
366
371
 
367
372
  Options:
368
373
 
369
- | Prop | Default | Description |
370
- | ------------------------ | ------- | --------------------------------------------------------------- |
371
- | `validateH1` | `true` | Warn about pages without exactly one `<h1>` |
372
- | `validateUniqueMetadata` | `true` | Warn about duplicate `<title>` or meta description across pages |
373
- | `indexNow` | — | Submit built URLs to IndexNow. See below for sub-options. |
374
+ | Prop | Default | Description |
375
+ | ------------------------ | ------- | ----------------------------------------------------------------- |
376
+ | `validateH1` | `true` | Warn about pages without exactly one `<h1>` |
377
+ | `validateUniqueMetadata` | `true` | Warn about duplicate `<title>` or meta description across pages |
378
+ | `indexNow` | — | Submit built URLs to IndexNow. See below for sub-options. |
374
379
  | `llmsTxt` | — | Generate `llms.txt` at the build root. See below for sub-options. |
375
380
 
376
381
  `indexNow` sub-options: `key` (8–128 hex chars), `host` (bare host, e.g.
@@ -409,7 +414,7 @@ own deploy hook.
409
414
  > sent before the key file is reachable in production get rejected
410
415
  > (HTTP 403) and the key is treated as invalid going forward — you'll
411
416
  > have to rotate it. Ship the route, deploy, confirm the `.txt` loads
412
- > over HTTPS, *then* enable `indexNow` in the integration.
417
+ > over HTTPS, _then_ enable `indexNow` in the integration.
413
418
 
414
419
  ## Validating your output
415
420
 
@@ -1,14 +1,125 @@
1
1
  ---
2
- import { SEO } from 'astro-seo';
3
- import { buildAstroSeoProps, type SeoProps } from './seo-props.js';
2
+ /**
3
+ * First-party <Seo> component. Consumes the flat `SeoContext` from
4
+ * `buildSeoContext()` and emits every `<head>` tag directly. No external
5
+ * `astro-seo` dependency.
6
+ *
7
+ * Tag order:
8
+ * 1. <title>
9
+ * 2. <link rel="canonical"> (omitted when noindex)
10
+ * 3. <meta name="description">
11
+ * 4. <meta name="robots"> (single merged tag)
12
+ * 5. og:title/type/image/url
13
+ * 6. og:description/site_name/locale/locale:alternate
14
+ * 7. og:image:alt/width/height (when og:image is set)
15
+ * 8. article:published_time/etc. (when ogType === 'article')
16
+ * 9. twitter:card/site/creator/...overrides
17
+ * 10. <link rel="alternate" hreflang> (incl. x-default)
18
+ * 11. <meta name="author">
19
+ * 12. extraLinks passthrough
20
+ * 13. extraMeta passthrough
21
+ * 14. <script type="application/ld+json"> (when graph is truthy)
22
+ */
23
+ import { buildSeoContext } from './seo-context.js';
24
+ import type { SeoProps } from './seo-props.js';
4
25
 
5
26
  const props = Astro.props as SeoProps;
6
- const astroSeo = buildAstroSeoProps(props, Astro.url.href);
27
+ const ctx = buildSeoContext(props, Astro.url.href);
28
+
29
+ function robotsContent(r: typeof ctx.robots): string {
30
+ const parts: string[] = [];
31
+ parts.push(r.noindex ? 'noindex' : 'index');
32
+ parts.push(r.nofollow ? 'nofollow' : 'follow');
33
+ if (r.extras) parts.push(r.extras);
34
+ return parts.join(', ');
35
+ }
7
36
  ---
8
37
 
9
- <SEO {...astroSeo} />
38
+ <title set:html={ctx.title} />
39
+
40
+ {ctx.canonical && <link rel="canonical" href={ctx.canonical} />}
41
+
42
+ {ctx.description && <meta name="description" content={ctx.description} />}
43
+
44
+ <meta name="robots" content={robotsContent(ctx.robots)} />
45
+
46
+ <meta property="og:title" content={ctx.og.title} />
47
+ <meta property="og:type" content={ctx.og.type} />
48
+ <meta property="og:image" content={ctx.og.image} />
49
+ <meta property="og:url" content={ctx.og.url} />
50
+
51
+ {ctx.og.description && <meta property="og:description" content={ctx.og.description} />}
52
+ {ctx.og.siteName && <meta property="og:site_name" content={ctx.og.siteName} />}
53
+ <meta property="og:locale" content={ctx.og.locale} />
54
+ {
55
+ ctx.og.localeAlternate?.map((entry) => (
56
+ <meta property="og:locale:alternate" content={entry} />
57
+ ))
58
+ }
59
+
60
+ {ctx.og.imageAlt && <meta property="og:image:alt" content={ctx.og.imageAlt} />}
61
+ {
62
+ ctx.og.imageWidth !== undefined && (
63
+ <meta property="og:image:width" content={String(ctx.og.imageWidth)} />
64
+ )
65
+ }
10
66
  {
11
- props.graph && (
12
- <script type="application/ld+json" set:html={JSON.stringify(props.graph)} />
67
+ ctx.og.imageHeight !== undefined && (
68
+ <meta property="og:image:height" content={String(ctx.og.imageHeight)} />
13
69
  )
14
70
  }
71
+
72
+ {
73
+ ctx.og.article && (
74
+ <>
75
+ {ctx.og.article.publishedTime && (
76
+ <meta property="article:published_time" content={ctx.og.article.publishedTime} />
77
+ )}
78
+ {ctx.og.article.modifiedTime && (
79
+ <meta property="article:modified_time" content={ctx.og.article.modifiedTime} />
80
+ )}
81
+ {ctx.og.article.expirationTime && (
82
+ <meta property="article:expiration_time" content={ctx.og.article.expirationTime} />
83
+ )}
84
+ {ctx.og.article.authors?.map((author) => (
85
+ <meta property="article:author" content={author} />
86
+ ))}
87
+ {ctx.og.article.tags?.map((tag) => <meta property="article:tag" content={tag} />)}
88
+ {ctx.og.article.section && (
89
+ <meta property="article:section" content={ctx.og.article.section} />
90
+ )}
91
+ {ctx.og.article.publisher && (
92
+ <meta property="article:publisher" content={ctx.og.article.publisher} />
93
+ )}
94
+ </>
95
+ )
96
+ }
97
+
98
+ {
99
+ ctx.twitter && (
100
+ <>
101
+ <meta name="twitter:card" content={ctx.twitter.card} />
102
+ {ctx.twitter.site && <meta name="twitter:site" content={ctx.twitter.site} />}
103
+ {ctx.twitter.creator && (
104
+ <meta name="twitter:creator" content={ctx.twitter.creator} />
105
+ )}
106
+ {ctx.twitter.title && <meta name="twitter:title" content={ctx.twitter.title} />}
107
+ {ctx.twitter.description && (
108
+ <meta name="twitter:description" content={ctx.twitter.description} />
109
+ )}
110
+ {ctx.twitter.image && <meta name="twitter:image" content={ctx.twitter.image} />}
111
+ {ctx.twitter.imageAlt && (
112
+ <meta name="twitter:image:alt" content={ctx.twitter.imageAlt} />
113
+ )}
114
+ </>
115
+ )
116
+ }
117
+
118
+ {ctx.hreflangs.map((entry) => <link rel="alternate" hreflang={entry.hreflang} href={entry.href} />)}
119
+
120
+ {ctx.authorName && <meta name="author" content={ctx.authorName} />}
121
+
122
+ {ctx.extraLinks.map((entry) => <link {...entry} />)}
123
+ {ctx.extraMeta.map((entry) => <meta {...entry} />)}
124
+
125
+ {ctx.graph && <script type="application/ld+json" set:html={JSON.stringify(ctx.graph)} />}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Normalized, flat, render-ready projection of `SeoProps`. The `<Seo>`
3
+ * template consumes this directly — no further reshaping, no
4
+ * conditionals beyond "field present?". Keeping normalization here (pure
5
+ * TypeScript) means vitest can assert on every decision without touching
6
+ * Astro's renderer.
7
+ */
8
+ import { type AlternateLink } from '../alternates.js';
9
+ import type { SeoProps } from './seo-props.js';
10
+ /**
11
+ * Opted-in robots directives for maximum snippet and preview sizes in
12
+ * search results. Appended after any `noindex`/`nofollow` prefix.
13
+ */
14
+ export declare const ROBOTS_EXTRAS = "max-snippet:-1, max-image-preview:large, max-video-preview:-1";
15
+ /**
16
+ * Render-ready normalization of `SeoProps`. Every field has been resolved
17
+ * against defaults, every `Date` coerced to ISO string, every optional
18
+ * block either populated or omitted. Templates just iterate.
19
+ */
20
+ export interface SeoContext {
21
+ /** Final `<title>` text, with `titleTemplate` already applied. */
22
+ title: string;
23
+ /** Meta description. Omitted from output when undefined. */
24
+ description?: string;
25
+ /**
26
+ * Canonical URL. Already query-stripped (or preserved) per
27
+ * `preserveQueryParams`. `undefined` when the page is `noindex` —
28
+ * callers must not emit a canonical in that case.
29
+ */
30
+ canonical?: string;
31
+ /** Resolved robots directives. Always present (extras always apply). */
32
+ robots: {
33
+ noindex: boolean;
34
+ nofollow: boolean;
35
+ /** Directives beyond noindex/nofollow — typically `ROBOTS_EXTRAS`. */
36
+ extras: string;
37
+ };
38
+ /**
39
+ * Open Graph fields. `title`, `type`, `url` are always populated.
40
+ * `image` may be an empty string when no share image was provided.
41
+ */
42
+ og: {
43
+ title: string;
44
+ type: string;
45
+ image: string;
46
+ url: string;
47
+ description?: string;
48
+ siteName?: string;
49
+ locale: string;
50
+ localeAlternate?: readonly string[];
51
+ imageAlt?: string;
52
+ imageWidth?: number;
53
+ imageHeight?: number;
54
+ article?: {
55
+ publishedTime?: string;
56
+ modifiedTime?: string;
57
+ expirationTime?: string;
58
+ authors?: readonly string[];
59
+ tags?: readonly string[];
60
+ section?: string;
61
+ publisher?: string;
62
+ };
63
+ };
64
+ /** Twitter tags. Omitted entirely when the caller passed no `twitter` block. */
65
+ twitter?: {
66
+ card: 'summary' | 'summary_large_image' | 'app' | 'player';
67
+ site?: string;
68
+ creator?: string;
69
+ title?: string;
70
+ description?: string;
71
+ image?: string;
72
+ imageAlt?: string;
73
+ };
74
+ /**
75
+ * hreflang alternate entries (including `x-default`). Empty array when
76
+ * the caller passed no `alternates`, or when fewer than 2 entries
77
+ * survive validation.
78
+ */
79
+ hreflangs: readonly AlternateLink[];
80
+ /** Resolved author name for `<meta name="author">`. */
81
+ authorName?: string;
82
+ /** Passthrough extras. Empty arrays when not provided. */
83
+ extraLinks: ReadonlyArray<Record<string, string>>;
84
+ extraMeta: ReadonlyArray<Record<string, string>>;
85
+ /** JSON-LD graph to inject. `null`/`undefined` → skip the script tag. */
86
+ graph?: Record<string, unknown> | null;
87
+ }
88
+ /**
89
+ * Build the flat `SeoContext` from user-provided `SeoProps` and the
90
+ * current page URL (usually `Astro.url.href`). Pure function; no Astro
91
+ * runtime access.
92
+ *
93
+ * Invariants worth knowing:
94
+ * - `canonical` is omitted when `noindex` is true (Google recommendation).
95
+ * - `og:url` falls back to the query-stripped page URL when canonical
96
+ * is omitted, so share previews stay stable even on noindex pages.
97
+ * - Twitter override fields are suppressed when they equal their OG
98
+ * counterparts (Twitter falls back to OG automatically, so emitting
99
+ * the duplicate is noise).
100
+ * - `og:locale:alternate` is derived from `alternates` by converting
101
+ * hyphenated BCP 47 to underscore form and skipping entries that
102
+ * match the primary locale.
103
+ */
104
+ export declare function buildSeoContext(props: SeoProps, pageUrl: string): SeoContext;
105
+ //# sourceMappingURL=seo-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-context.d.ts","sourceRoot":"","sources":["../../src/components/seo-context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,aAAa,kEAAkE,CAAC;AAE7F;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACvB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,MAAM,EAAE;QACJ,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,sEAAsE;QACtE,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;OAGG;IACH,EAAE,EAAE;QACA,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE;YACN,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,cAAc,CAAC,EAAE,MAAM,CAAC;YACxB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YACzB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,SAAS,CAAC,EAAE,MAAM,CAAC;SACtB,CAAC;KACL,CAAC;IACF,gFAAgF;IAChF,OAAO,CAAC,EAAE;QACN,IAAI,EAAE,SAAS,GAAG,qBAAqB,GAAG,KAAK,GAAG,QAAQ,CAAC;QAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF;;;;OAIG;IACH,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAiBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAmI5E"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Normalized, flat, render-ready projection of `SeoProps`. The `<Seo>`
3
+ * template consumes this directly — no further reshaping, no
4
+ * conditionals beyond "field present?". Keeping normalization here (pure
5
+ * TypeScript) means vitest can assert on every decision without touching
6
+ * Astro's renderer.
7
+ */
8
+ import { buildAlternateLinks } from '../alternates.js';
9
+ /**
10
+ * Opted-in robots directives for maximum snippet and preview sizes in
11
+ * search results. Appended after any `noindex`/`nofollow` prefix.
12
+ */
13
+ export const ROBOTS_EXTRAS = 'max-snippet:-1, max-image-preview:large, max-video-preview:-1';
14
+ function toIsoString(value) {
15
+ if (value === undefined)
16
+ return undefined;
17
+ return value instanceof Date ? value.toISOString() : value;
18
+ }
19
+ function stripQueryParams(url) {
20
+ try {
21
+ const parsed = new URL(url);
22
+ parsed.search = '';
23
+ return parsed.toString();
24
+ }
25
+ catch {
26
+ return url;
27
+ }
28
+ }
29
+ /**
30
+ * Build the flat `SeoContext` from user-provided `SeoProps` and the
31
+ * current page URL (usually `Astro.url.href`). Pure function; no Astro
32
+ * runtime access.
33
+ *
34
+ * Invariants worth knowing:
35
+ * - `canonical` is omitted when `noindex` is true (Google recommendation).
36
+ * - `og:url` falls back to the query-stripped page URL when canonical
37
+ * is omitted, so share previews stay stable even on noindex pages.
38
+ * - Twitter override fields are suppressed when they equal their OG
39
+ * counterparts (Twitter falls back to OG automatically, so emitting
40
+ * the duplicate is noise).
41
+ * - `og:locale:alternate` is derived from `alternates` by converting
42
+ * hyphenated BCP 47 to underscore form and skipping entries that
43
+ * match the primary locale.
44
+ */
45
+ export function buildSeoContext(props, pageUrl) {
46
+ const fullTitle = props.titleTemplate
47
+ ? props.titleTemplate.replace('%s', props.title)
48
+ : props.title;
49
+ // Canonical: explicit > preserveQueryParams > strip query. Omitted
50
+ // entirely when noindex (Google recommendation).
51
+ let canonical;
52
+ if (props.canonical !== undefined) {
53
+ canonical = props.canonical.toString();
54
+ }
55
+ else if (props.preserveQueryParams) {
56
+ canonical = pageUrl;
57
+ }
58
+ else {
59
+ canonical = stripQueryParams(pageUrl);
60
+ }
61
+ if (props.noindex)
62
+ canonical = undefined;
63
+ // og:url still points at the canonical or stripped page URL even
64
+ // when canonical is omitted — share previews shouldn't carry query
65
+ // params.
66
+ const ogUrl = canonical ?? stripQueryParams(pageUrl);
67
+ const ogType = props.ogType ?? 'website';
68
+ const ogImage = props.ogImage ?? '';
69
+ const locale = props.locale ?? 'en_US';
70
+ const og = {
71
+ title: fullTitle,
72
+ type: ogType,
73
+ image: ogImage,
74
+ url: ogUrl,
75
+ locale,
76
+ };
77
+ if (props.description !== undefined)
78
+ og.description = props.description;
79
+ if (props.siteName !== undefined)
80
+ og.siteName = props.siteName;
81
+ // og:locale:alternate: convert hyphens → underscores, skip dupes, skip
82
+ // the primary locale, and skip language-only entries whose language
83
+ // already matches the primary.
84
+ if (props.alternates?.entries && props.alternates.entries.length > 1) {
85
+ const primaryLang = locale.split('_')[0]?.toLowerCase();
86
+ const localeAlternate = [];
87
+ const seen = new Set();
88
+ for (const entry of props.alternates.entries) {
89
+ const ogLocale = entry.hreflang.replace('-', '_');
90
+ const entryLang = entry.hreflang.split('-')[0]?.toLowerCase();
91
+ if (seen.has(ogLocale))
92
+ continue;
93
+ if (ogLocale === locale)
94
+ continue;
95
+ if (!entry.hreflang.includes('-') && entryLang === primaryLang)
96
+ continue;
97
+ seen.add(ogLocale);
98
+ localeAlternate.push(ogLocale);
99
+ }
100
+ if (localeAlternate.length > 0)
101
+ og.localeAlternate = localeAlternate;
102
+ }
103
+ // OG image metadata: only when at least one dimension/alt is set, and
104
+ // only when an image URL is actually present (width/height without a
105
+ // URL is meaningless).
106
+ if (ogImage) {
107
+ if (props.ogImageAlt !== undefined)
108
+ og.imageAlt = props.ogImageAlt;
109
+ if (props.ogImageWidth !== undefined)
110
+ og.imageWidth = props.ogImageWidth;
111
+ if (props.ogImageHeight !== undefined)
112
+ og.imageHeight = props.ogImageHeight;
113
+ }
114
+ // Article metadata: only when ogType === 'article'.
115
+ if (ogType === 'article' && (props.article || props.articlePublisher)) {
116
+ const article = {};
117
+ if (props.article) {
118
+ const published = toIsoString(props.article.publishedTime);
119
+ if (published !== undefined)
120
+ article.publishedTime = published;
121
+ const modified = toIsoString(props.article.modifiedTime);
122
+ if (modified !== undefined)
123
+ article.modifiedTime = modified;
124
+ const expiration = toIsoString(props.article.expirationTime);
125
+ if (expiration !== undefined)
126
+ article.expirationTime = expiration;
127
+ if (props.article.authors !== undefined)
128
+ article.authors = props.article.authors;
129
+ if (props.article.tags !== undefined)
130
+ article.tags = props.article.tags;
131
+ if (props.article.section !== undefined)
132
+ article.section = props.article.section;
133
+ }
134
+ if (props.articlePublisher !== undefined)
135
+ article.publisher = props.articlePublisher;
136
+ og.article = article;
137
+ }
138
+ // Twitter: suppress overrides that equal their OG counterpart.
139
+ let twitter;
140
+ if (props.twitter !== undefined) {
141
+ const t = {
142
+ card: props.twitter.card ?? 'summary_large_image',
143
+ };
144
+ if (props.twitter.site !== undefined)
145
+ t.site = props.twitter.site;
146
+ if (props.twitter.creator !== undefined)
147
+ t.creator = props.twitter.creator;
148
+ if (props.twitter.title !== undefined && props.twitter.title !== fullTitle) {
149
+ t.title = props.twitter.title;
150
+ }
151
+ if (props.twitter.description !== undefined &&
152
+ props.twitter.description !== props.description) {
153
+ t.description = props.twitter.description;
154
+ }
155
+ if (props.twitter.image !== undefined && props.twitter.image !== ogImage) {
156
+ t.image = props.twitter.image;
157
+ }
158
+ if (props.twitter.imageAlt !== undefined && props.twitter.imageAlt !== props.ogImageAlt) {
159
+ t.imageAlt = props.twitter.imageAlt;
160
+ }
161
+ twitter = t;
162
+ }
163
+ const hreflangs = props.alternates !== undefined ? buildAlternateLinks(props.alternates) : [];
164
+ const authorName = props.author ?? props.article?.authors?.[0];
165
+ const ctx = {
166
+ title: fullTitle,
167
+ robots: {
168
+ noindex: props.noindex === true,
169
+ nofollow: props.nofollow === true,
170
+ extras: ROBOTS_EXTRAS,
171
+ },
172
+ og,
173
+ hreflangs,
174
+ extraLinks: props.extraLinks ?? [],
175
+ extraMeta: props.extraMeta ?? [],
176
+ };
177
+ if (canonical !== undefined)
178
+ ctx.canonical = canonical;
179
+ if (props.description !== undefined)
180
+ ctx.description = props.description;
181
+ if (twitter !== undefined)
182
+ ctx.twitter = twitter;
183
+ if (authorName !== undefined)
184
+ ctx.authorName = authorName;
185
+ if (props.graph !== undefined)
186
+ ctx.graph = props.graph;
187
+ return ctx;
188
+ }
189
+ //# sourceMappingURL=seo-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-context.js","sourceRoot":"","sources":["../../src/components/seo-context.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,9 @@
1
1
  /**
2
- * Pure TypeScript layer for the <Seo> component. The .astro file is a
3
- * thin template that calls `buildAstroSeoProps` with the user's input
4
- * and an Astro context (mostly `Astro.url.href`). Keeping the logic
5
- * here makes it unit-testable with vitest — Astro's renderer isn't
6
- * easily accessible from vitest.
2
+ * Public props surface of the <Seo> component. The `.astro` template
3
+ * normalizes these via `buildSeoContext` (in `seo-context.ts`) and
4
+ * renders the resulting flat shape directly no intermediate adapter.
7
5
  */
8
- import { type BuildAlternateLinksInput } from '../alternates.js';
6
+ import type { BuildAlternateLinksInput } from '../alternates.js';
9
7
  /** Public props surface of the <Seo> component. */
10
8
  export interface SeoProps {
11
9
  /** Page title. Required. */
@@ -118,65 +116,4 @@ export interface SeoProps {
118
116
  */
119
117
  alternates?: BuildAlternateLinksInput;
120
118
  }
121
- /**
122
- * Shape consumed by `astro-seo`'s `<SEO>` component. We expose it as a
123
- * type so tests can assert on exact keys / nesting rather than having
124
- * to parse rendered HTML.
125
- */
126
- export interface AstroSeoProps {
127
- title: string;
128
- description?: string;
129
- canonical?: string;
130
- openGraph: {
131
- basic: {
132
- title: string;
133
- type: string;
134
- image: string;
135
- url: string;
136
- };
137
- optional?: {
138
- description?: string;
139
- siteName?: string;
140
- locale?: string;
141
- localeAlternate?: string[];
142
- };
143
- image?: {
144
- alt?: string;
145
- width?: number;
146
- height?: number;
147
- };
148
- article?: {
149
- publishedTime?: string;
150
- modifiedTime?: string;
151
- expirationTime?: string;
152
- authors?: string[];
153
- tags?: string[];
154
- section?: string;
155
- publisher?: string;
156
- };
157
- };
158
- twitter?: {
159
- card: 'summary' | 'summary_large_image' | 'app' | 'player';
160
- site?: string;
161
- creator?: string;
162
- title?: string;
163
- description?: string;
164
- image?: string;
165
- imageAlt?: string;
166
- };
167
- extend?: {
168
- link?: Array<Record<string, string>>;
169
- meta?: Array<Record<string, string>>;
170
- };
171
- }
172
- /**
173
- * Project the public `SeoProps` onto the shape `astro-seo`'s `<SEO>`
174
- * component expects. Pure function; no Astro runtime access.
175
- *
176
- * @param props Props as provided by the user.
177
- * @param pageUrl The current page URL — usually `Astro.url.href`.
178
- * Used as the canonical URL when `props.canonical` is
179
- * not provided, and as the base for the OG `url`.
180
- */
181
- export declare function buildAstroSeoProps(props: SeoProps, pageUrl: string): AstroSeoProps;
182
119
  //# sourceMappingURL=seo-props.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"seo-props.d.ts","sourceRoot":"","sources":["../../src/components/seo-props.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seo-props.d.ts","sourceRoot":"","sources":["../../src/components/seo-props.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,mDAAmD;AACnD,MAAM,WAAW,QAAQ;IACrB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACzB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gDAAgD;IAChD,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACpD,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE;QACN,2DAA2D;QAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,oCAAoC;QACpC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,sDAAsD;QACtD,IAAI,CAAC,EAAE,SAAS,GAAG,qBAAqB,GAAG,KAAK,GAAG,QAAQ,CAAC;QAC5D,6DAA6D;QAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,yEAAyE;QACzE,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,6DAA6D;QAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,qEAAqE;QACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF;;;OAGG;IACH,OAAO,CAAC,EAAE;QACN,aAAa,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;QAC9B,YAAY,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;QAC7B,cAAc,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;QAC/B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC5B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,OAAO,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACvC,iEAAiE;IACjE,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,mDAAmD;IACnD,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,wBAAwB,CAAC;CACzC"}
@@ -1,236 +1,7 @@
1
1
  /**
2
- * Pure TypeScript layer for the <Seo> component. The .astro file is a
3
- * thin template that calls `buildAstroSeoProps` with the user's input
4
- * and an Astro context (mostly `Astro.url.href`). Keeping the logic
5
- * here makes it unit-testable with vitest — Astro's renderer isn't
6
- * easily accessible from vitest.
2
+ * Public props surface of the <Seo> component. The `.astro` template
3
+ * normalizes these via `buildSeoContext` (in `seo-context.ts`) and
4
+ * renders the resulting flat shape directly no intermediate adapter.
7
5
  */
8
- import { buildAlternateLinks } from '../alternates.js';
9
- function toIsoString(value) {
10
- if (value === undefined)
11
- return undefined;
12
- return value instanceof Date ? value.toISOString() : value;
13
- }
14
- /**
15
- * Build the `content` value of the `<meta name="robots">` tag. Always
16
- * includes `max-snippet:-1, max-image-preview:large, max-video-preview:-1`
17
- * (opt into maximum snippet/preview sizes in search results). Prepends
18
- * `noindex`, `nofollow`, or `noindex, follow` as applicable.
19
- */
20
- function buildRobotsContent(noindex, nofollow) {
21
- const directives = [];
22
- if (noindex && nofollow) {
23
- directives.push('noindex', 'nofollow');
24
- }
25
- else if (noindex) {
26
- directives.push('noindex', 'follow');
27
- }
28
- else if (nofollow) {
29
- directives.push('nofollow');
30
- }
31
- directives.push('max-snippet:-1', 'max-image-preview:large', 'max-video-preview:-1');
32
- return directives.join(', ');
33
- }
34
- /**
35
- * Strip the query string from a URL. Fragments are preserved. Falls
36
- * back to returning the input unchanged if URL parsing fails.
37
- */
38
- function stripQueryParams(url) {
39
- try {
40
- const parsed = new URL(url);
41
- parsed.search = '';
42
- return parsed.toString();
43
- }
44
- catch {
45
- return url;
46
- }
47
- }
48
- /**
49
- * Project the public `SeoProps` onto the shape `astro-seo`'s `<SEO>`
50
- * component expects. Pure function; no Astro runtime access.
51
- *
52
- * @param props Props as provided by the user.
53
- * @param pageUrl The current page URL — usually `Astro.url.href`.
54
- * Used as the canonical URL when `props.canonical` is
55
- * not provided, and as the base for the OG `url`.
56
- */
57
- export function buildAstroSeoProps(props, pageUrl) {
58
- const fullTitle = props.titleTemplate
59
- ? props.titleTemplate.replace('%s', props.title)
60
- : props.title;
61
- // Default canonical strips query params (SEO-correct for most
62
- // cases). `preserveQueryParams` opts out. Explicit `canonical`
63
- // overrides entirely.
64
- let canonical;
65
- if (props.canonical !== undefined) {
66
- canonical = props.canonical.toString();
67
- }
68
- else if (props.preserveQueryParams) {
69
- canonical = pageUrl;
70
- }
71
- else {
72
- canonical = stripQueryParams(pageUrl);
73
- }
74
- // Omit canonical when the page is noindex (Google recommendation).
75
- if (props.noindex) {
76
- canonical = undefined;
77
- }
78
- // og:url uses the canonical when available, otherwise the (possibly
79
- // query-stripped) page URL.
80
- const ogUrl = canonical ?? stripQueryParams(pageUrl);
81
- const ogType = props.ogType ?? 'website';
82
- const ogImage = props.ogImage ?? '';
83
- const openGraph = {
84
- basic: {
85
- title: fullTitle,
86
- type: ogType,
87
- image: ogImage,
88
- url: ogUrl,
89
- },
90
- };
91
- const optional = {};
92
- if (props.description !== undefined)
93
- optional.description = props.description;
94
- if (props.siteName !== undefined)
95
- optional.siteName = props.siteName;
96
- optional.locale = props.locale ?? 'en_US';
97
- // og:locale:alternate from hreflang entries. Convert hyphenated
98
- // BCP 47 (fr-CA) to OG-style underscores (fr_CA), and skip any
99
- // entry that matches the primary og:locale (including language-only
100
- // matches like hreflang='en' when og:locale='en_US').
101
- if (props.alternates?.entries && props.alternates.entries.length > 1) {
102
- const primaryLang = optional.locale?.split('_')[0]?.toLowerCase();
103
- const localeAlternate = [];
104
- const seen = new Set();
105
- for (const entry of props.alternates.entries) {
106
- const ogLocale = entry.hreflang.replace('-', '_');
107
- const entryLang = entry.hreflang.split('-')[0]?.toLowerCase();
108
- if (seen.has(ogLocale))
109
- continue;
110
- if (ogLocale === optional.locale)
111
- continue;
112
- // Skip language-only hreflang when it matches the primary locale's language.
113
- if (!entry.hreflang.includes('-') && entryLang === primaryLang)
114
- continue;
115
- seen.add(ogLocale);
116
- localeAlternate.push(ogLocale);
117
- }
118
- if (localeAlternate.length > 0)
119
- optional.localeAlternate = localeAlternate;
120
- }
121
- openGraph.optional = optional;
122
- const hasImageMeta = props.ogImageAlt !== undefined ||
123
- props.ogImageWidth !== undefined ||
124
- props.ogImageHeight !== undefined;
125
- if (ogImage && hasImageMeta) {
126
- const image = {};
127
- if (props.ogImageAlt !== undefined)
128
- image.alt = props.ogImageAlt;
129
- if (props.ogImageWidth !== undefined)
130
- image.width = props.ogImageWidth;
131
- if (props.ogImageHeight !== undefined)
132
- image.height = props.ogImageHeight;
133
- openGraph.image = image;
134
- }
135
- if (ogType === 'article' && (props.article || props.articlePublisher)) {
136
- const article = {};
137
- if (props.article) {
138
- const published = toIsoString(props.article.publishedTime);
139
- if (published !== undefined)
140
- article.publishedTime = published;
141
- const modified = toIsoString(props.article.modifiedTime);
142
- if (modified !== undefined)
143
- article.modifiedTime = modified;
144
- const expiration = toIsoString(props.article.expirationTime);
145
- if (expiration !== undefined)
146
- article.expirationTime = expiration;
147
- if (props.article.authors !== undefined)
148
- article.authors = [...props.article.authors];
149
- if (props.article.tags !== undefined)
150
- article.tags = [...props.article.tags];
151
- if (props.article.section !== undefined)
152
- article.section = props.article.section;
153
- }
154
- if (props.articlePublisher !== undefined)
155
- article.publisher = props.articlePublisher;
156
- openGraph.article = article;
157
- }
158
- const astroSeo = {
159
- title: fullTitle,
160
- openGraph,
161
- };
162
- if (canonical !== undefined)
163
- astroSeo.canonical = canonical;
164
- if (props.description !== undefined)
165
- astroSeo.description = props.description;
166
- if (props.twitter !== undefined) {
167
- const twitter = {
168
- card: props.twitter.card ?? 'summary_large_image',
169
- };
170
- if (props.twitter.site !== undefined)
171
- twitter.site = props.twitter.site;
172
- if (props.twitter.creator !== undefined)
173
- twitter.creator = props.twitter.creator;
174
- // Only emit twitter:title/description/image/imageAlt when the
175
- // caller explicitly provided Twitter-specific overrides.
176
- // Otherwise Twitter falls back to the og: counterparts
177
- // automatically — emitting duplicates is noisy.
178
- if (props.twitter.title !== undefined && props.twitter.title !== fullTitle) {
179
- twitter.title = props.twitter.title;
180
- }
181
- if (props.twitter.description !== undefined &&
182
- props.twitter.description !== props.description) {
183
- twitter.description = props.twitter.description;
184
- }
185
- if (props.twitter.image !== undefined && props.twitter.image !== ogImage) {
186
- twitter.image = props.twitter.image;
187
- }
188
- if (props.twitter.imageAlt !== undefined && props.twitter.imageAlt !== props.ogImageAlt) {
189
- twitter.imageAlt = props.twitter.imageAlt;
190
- }
191
- astroSeo.twitter = twitter;
192
- }
193
- // Resolve hreflang alternates (if any). Returns [] when fewer than
194
- // 2 entries survive validation, so this is cheap to call.
195
- const alternateLinks = props.alternates !== undefined ? buildAlternateLinks(props.alternates) : [];
196
- // Build our own robots meta (astro-seo's doesn't support max-*).
197
- const robotsContent = buildRobotsContent(props.noindex, props.nofollow);
198
- // Resolve author name: explicit prop takes precedence, falls back
199
- // to first entry in article.authors.
200
- const authorName = props.author ?? props.article?.authors?.[0];
201
- const meta = [];
202
- meta.push({ name: 'robots', content: robotsContent });
203
- if (authorName !== undefined) {
204
- meta.push({ name: 'author', content: authorName });
205
- }
206
- if (props.extraMeta !== undefined) {
207
- for (const entry of props.extraMeta)
208
- meta.push({ ...entry });
209
- }
210
- const hasExtraLinks = props.extraLinks !== undefined && props.extraLinks.length > 0;
211
- const hasAlternates = alternateLinks.length > 0;
212
- const link = [];
213
- if (hasExtraLinks) {
214
- for (const entry of props.extraLinks)
215
- link.push({ ...entry });
216
- }
217
- if (hasAlternates) {
218
- for (const entry of alternateLinks) {
219
- link.push({
220
- rel: entry.rel,
221
- href: entry.href,
222
- hreflang: entry.hreflang,
223
- });
224
- }
225
- }
226
- const extend = {};
227
- if (link.length > 0)
228
- extend.link = link;
229
- if (meta.length > 0)
230
- extend.meta = meta;
231
- if (extend.link !== undefined || extend.meta !== undefined) {
232
- astroSeo.extend = extend;
233
- }
234
- return astroSeo;
235
- }
6
+ export {};
236
7
  //# sourceMappingURL=seo-props.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"seo-props.js","sourceRoot":"","sources":["../../src/components/seo-props.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seo-props.js","sourceRoot":"","sources":["../../src/components/seo-props.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/dist/index.d.ts CHANGED
@@ -3,8 +3,9 @@ export type { AggregatorOptions, AggregatedGraph } from './aggregator.js';
3
3
  export { createSchemaEndpoint, createSchemaMap } from './routes.js';
4
4
  export type { SchemaEndpointOptions, SchemaMapEntry, SchemaMapOptions } from './routes.js';
5
5
  export { seoSchema, imageSchema } from './content-helpers.js';
6
- export { buildAstroSeoProps } from './components/seo-props.js';
7
- export type { SeoProps, AstroSeoProps } from './components/seo-props.js';
6
+ export type { SeoProps } from './components/seo-props.js';
7
+ export { buildSeoContext, ROBOTS_EXTRAS } from './components/seo-context.js';
8
+ export type { SeoContext } from './components/seo-context.js';
8
9
  export { buildAlternateLinks } from './alternates.js';
9
10
  export type { AlternateLink, BuildAlternateLinksInput } from './alternates.js';
10
11
  export { breadcrumbsFromUrl } from './breadcrumbs.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3F,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAEzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC9F,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3F,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE9D,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC7E,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC9F,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  export { aggregate } from './aggregator.js';
7
7
  export { createSchemaEndpoint, createSchemaMap } from './routes.js';
8
8
  export { seoSchema, imageSchema } from './content-helpers.js';
9
- export { buildAstroSeoProps } from './components/seo-props.js';
9
+ export { buildSeoContext, ROBOTS_EXTRAS } from './components/seo-context.js';
10
10
  export { buildAlternateLinks } from './alternates.js';
11
11
  export { breadcrumbsFromUrl } from './breadcrumbs.js';
12
12
  export { createIndexNowKeyRoute, submitToIndexNow, validateIndexNowKey } from './indexnow.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,wEAAwE;AACxE,8EAA8E;AAC9E,sDAAsD;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAG9F,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,wEAAwE;AACxE,8EAA8E;AAC9E,sDAAsD;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG9D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAG9F,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAKnE,UAAU,aAAa;IACnB,GAAG,EAAE,GAAG,CAAC;IAET,MAAM,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;CAC5F;AAED,UAAU,oBAAoB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACtE,CAAC;CACL;AAED,MAAM,WAAW,0BAA0B;IACvC,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,yBAAyB;IACtC,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,0BAA0B,CAAC;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAc3E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAgBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKxD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQlE;AAgBD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,OAAO,GAAE,0BAA+B,GAAG,oBAAoB,CAqK/F"}
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAKnE,UAAU,aAAa;IACnB,GAAG,EAAE,GAAG,CAAC;IAET,MAAM,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;CAC5F;AAED,UAAU,oBAAoB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACtE,CAAC;CACL;AAED,MAAM,WAAW,0BAA0B;IACvC,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,yBAAyB;IACtC,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,0BAA0B,CAAC;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAc3E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAgBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKxD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQlE;AAgBD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,OAAO,GAAE,0BAA+B,GAAG,oBAAoB,CA4J/F"}
@@ -106,7 +106,7 @@ async function collectHtmlFiles(dir, base = dir) {
106
106
  * ```
107
107
  */
108
108
  export default function seoGraph(options = {}) {
109
- const { validateH1 = true, validateUniqueMetadata = true, indexNow, llmsTxt, } = options;
109
+ const { validateH1 = true, validateUniqueMetadata = true, indexNow, llmsTxt } = options;
110
110
  const autoLlmsTxt = llmsTxt && !llmsTxt.sections;
111
111
  return {
112
112
  name: '@jdevalk/astro-seo-graph',
@@ -114,9 +114,7 @@ export default function seoGraph(options = {}) {
114
114
  'astro:build:done': async ({ dir, logger }) => {
115
115
  const buildDir = fileURLToPath(dir);
116
116
  const needsContentScan = validateH1 || validateUniqueMetadata || autoLlmsTxt;
117
- const htmlFiles = needsContentScan || indexNow || llmsTxt
118
- ? await collectHtmlFiles(buildDir)
119
- : [];
117
+ const htmlFiles = needsContentScan || indexNow || llmsTxt ? await collectHtmlFiles(buildDir) : [];
120
118
  const autoLinks = [];
121
119
  const h1Missing = [];
122
120
  const h1Multiple = [];
@@ -217,8 +215,9 @@ export default function seoGraph(options = {}) {
217
215
  }
218
216
  }
219
217
  if (llmsTxt) {
220
- const sections = llmsTxt.sections ??
221
- [{ name: llmsTxt.autoSectionName ?? 'Pages', links: autoLinks }];
218
+ const sections = llmsTxt.sections ?? [
219
+ { name: llmsTxt.autoSectionName ?? 'Pages', links: autoLinks },
220
+ ];
222
221
  const rendered = renderLlmsTxt({
223
222
  title: llmsTxt.title,
224
223
  summary: llmsTxt.summary,
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration.js","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jdevalk/astro-seo-graph",
3
- "version": "0.9.0",
3
+ "version": "1.0.0",
4
4
  "description": "Astro integration for @jdevalk/seo-graph-core. Seo component, route factories, content-collection aggregator, Zod content helpers.",
5
5
  "keywords": [
6
6
  "astro",
@@ -49,7 +49,6 @@
49
49
  "astro": "^5.0.0 || ^6.0.0"
50
50
  },
51
51
  "dependencies": {
52
- "astro-seo": "^1.1.0",
53
52
  "schema-dts": "^2.0.0",
54
53
  "zod": "^3.24.0",
55
54
  "@jdevalk/seo-graph-core": "0.6.1"
@@ -58,7 +57,7 @@
58
57
  "@types/node": "^22.0.0",
59
58
  "astro": "^6.0.5",
60
59
  "typescript": "^5.6.0",
61
- "vitest": "^2.0.0"
60
+ "vitest": "^3.2.4"
62
61
  },
63
62
  "scripts": {
64
63
  "build": "tsc -p tsconfig.build.json && mkdir -p dist/components && cp src/components/*.astro dist/components/ && cp ../../AGENTS.md .",