@growth-labs/seo 0.2.7 → 0.2.8

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.
Files changed (70) hide show
  1. package/README.md +20 -7
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/options.d.ts +67 -40
  7. package/dist/options.d.ts.map +1 -1
  8. package/dist/options.js +11 -1
  9. package/dist/options.js.map +1 -1
  10. package/dist/routes/apple-news.d.ts.map +1 -1
  11. package/dist/routes/apple-news.js +2 -1
  12. package/dist/routes/apple-news.js.map +1 -1
  13. package/dist/routes/podcast-narration.d.ts.map +1 -1
  14. package/dist/routes/podcast-narration.js +2 -1
  15. package/dist/routes/podcast-narration.js.map +1 -1
  16. package/dist/routes/podcast.d.ts.map +1 -1
  17. package/dist/routes/podcast.js +2 -1
  18. package/dist/routes/podcast.js.map +1 -1
  19. package/dist/routes/revalidate.d.ts.map +1 -1
  20. package/dist/routes/revalidate.js +4 -2
  21. package/dist/routes/revalidate.js.map +1 -1
  22. package/dist/routes/robots.d.ts.map +1 -1
  23. package/dist/routes/robots.js +2 -1
  24. package/dist/routes/robots.js.map +1 -1
  25. package/dist/routes/rss.d.ts.map +1 -1
  26. package/dist/routes/rss.js +2 -1
  27. package/dist/routes/rss.js.map +1 -1
  28. package/dist/routes/sitemap-index.d.ts.map +1 -1
  29. package/dist/routes/sitemap-index.js +2 -1
  30. package/dist/routes/sitemap-index.js.map +1 -1
  31. package/dist/runtime.d.ts +1 -5
  32. package/dist/runtime.d.ts.map +1 -1
  33. package/dist/runtime.js +3 -5
  34. package/dist/runtime.js.map +1 -1
  35. package/dist/site-url-core.d.ts +10 -0
  36. package/dist/site-url-core.d.ts.map +1 -0
  37. package/dist/site-url-core.js +46 -0
  38. package/dist/site-url-core.js.map +1 -0
  39. package/dist/site-url.d.ts +5 -0
  40. package/dist/site-url.d.ts.map +1 -0
  41. package/dist/site-url.js +9 -0
  42. package/dist/site-url.js.map +1 -0
  43. package/dist/utils/apple-news-rss.d.ts +2 -2
  44. package/dist/utils/apple-news-rss.d.ts.map +1 -1
  45. package/dist/utils/index.d.ts +1 -0
  46. package/dist/utils/index.d.ts.map +1 -1
  47. package/dist/utils/index.js +1 -0
  48. package/dist/utils/index.js.map +1 -1
  49. package/dist/utils/json-ld/organization.d.ts +2 -2
  50. package/dist/utils/json-ld/organization.d.ts.map +1 -1
  51. package/dist/utils/json-ld/organization.js.map +1 -1
  52. package/dist/utils/json-ld/website.d.ts +2 -2
  53. package/dist/utils/json-ld/website.d.ts.map +1 -1
  54. package/dist/utils/json-ld/website.js.map +1 -1
  55. package/dist/utils/podcast.d.ts +2 -2
  56. package/dist/utils/podcast.d.ts.map +1 -1
  57. package/dist/utils/podcast.js.map +1 -1
  58. package/dist/utils/robots.d.ts +2 -2
  59. package/dist/utils/robots.d.ts.map +1 -1
  60. package/dist/utils/robots.js.map +1 -1
  61. package/dist/utils/rss.d.ts +2 -2
  62. package/dist/utils/rss.d.ts.map +1 -1
  63. package/dist/utils/rss.js.map +1 -1
  64. package/dist/utils/seo-head.d.ts +22 -0
  65. package/dist/utils/seo-head.d.ts.map +1 -0
  66. package/dist/utils/seo-head.js +40 -0
  67. package/dist/utils/seo-head.js.map +1 -0
  68. package/package.json +5 -1
  69. package/src/components/AeoHead.astro +2 -1
  70. package/src/components/SeoHead.astro +30 -10
@@ -9,6 +9,7 @@ import 'virtual:growth-labs/seo/config'
9
9
  // src/options.js inside the consumer's node_modules. Package specifiers route
10
10
  // through the exports map to the compiled dist output.
11
11
  import { getConfig, resolveAeoTwins } from '@growth-labs/seo'
12
+ import { resolveSeoConfig } from '@growth-labs/seo/site-url'
12
13
 
13
14
  export interface Props {
14
15
  /**
@@ -32,7 +33,7 @@ export interface Props {
32
33
  }
33
34
 
34
35
  const { canonical, emitTwinLink = true } = Astro.props
35
- const config = getConfig()
36
+ const config = resolveSeoConfig(getConfig())
36
37
  const aeo = resolveAeoTwins(config.aeoTwins)
37
38
 
38
39
  // ─── Apple News discovery link ───
@@ -23,8 +23,10 @@
23
23
  import 'virtual:growth-labs/seo/config'
24
24
 
25
25
  import { getConfig, type ContentItem } from '@growth-labs/seo'
26
+ import { resolveSeoConfig } from '@growth-labs/seo/site-url'
26
27
  import {
27
- generateArticleJsonLd,
28
+ buildSeoHeadJsonLd,
29
+ buildSeoHeadTitleDescription,
28
30
  generateCanonical,
29
31
  generateHreflang,
30
32
  generateMeta,
@@ -76,6 +78,13 @@ export interface Props {
76
78
  * have a twin), false otherwise (homepage doesn't).
77
79
  */
78
80
  emitTwinLink?: boolean
81
+
82
+ /**
83
+ * Explicit document title/description overrides. When omitted, title and
84
+ * description come from the content item, then the organization name.
85
+ */
86
+ title?: string
87
+ description?: string
79
88
  }
80
89
 
81
90
  const {
@@ -85,9 +94,12 @@ const {
85
94
  emitJsonLd,
86
95
  canonical,
87
96
  emitTwinLink,
97
+ title,
98
+ description,
88
99
  } = Astro.props
89
100
 
90
- const config = getConfig()
101
+ const config = resolveSeoConfig(getConfig())
102
+ const titleDescription = buildSeoHeadTitleDescription({ item, options: config, title, description })
91
103
 
92
104
  // Canonical: item.url if item provided, else explicit prop, else Astro.url.
93
105
  const canonicalHref = (() => {
@@ -98,7 +110,9 @@ const canonicalHref = (() => {
98
110
  const canonicalLink = generateCanonical(canonicalHref, config)
99
111
 
100
112
  // Meta tags (OG + Twitter + news_keywords + apple-news-*): item required.
101
- const metaTags = item ? generateMeta(item, variant, config) : []
113
+ const metaTags = item
114
+ ? generateMeta(item, variant, config).filter((tag) => tag.name !== 'robots')
115
+ : []
102
116
 
103
117
  // Hreflang: item's alternateLocales when present. generateHreflang tolerates
104
118
  // empty input; we gate on length anyway to avoid a call when unnecessary.
@@ -106,16 +120,22 @@ const hreflangLinks = item?.alternateLocales?.length
106
120
  ? generateHreflang(item.alternateLocales, config.defaultLocale ?? 'en')
107
121
  : []
108
122
 
109
- // JSON-LD emission default: on when item + variant are set.
110
- const shouldEmitJsonLd = emitJsonLd ?? Boolean(item)
111
- const jsonLd = shouldEmitJsonLd && item && variant === 'article'
112
- ? generateArticleJsonLd(item, config)
113
- : null
123
+ // JSON-LD emission default: on for both global and content pages.
124
+ const shouldEmitJsonLd = emitJsonLd ?? true
125
+ const jsonLdEntries = buildSeoHeadJsonLd({
126
+ item,
127
+ options: config,
128
+ variant,
129
+ emitJsonLd: shouldEmitJsonLd,
130
+ })
114
131
 
115
132
  // Twin-link default: on when there's an item (article-ish page), off otherwise.
116
133
  const shouldEmitTwinLink = emitTwinLink ?? Boolean(item)
117
134
  ---
118
135
 
136
+ <title>{titleDescription.title}</title>
137
+ {titleDescription.description && <meta name="description" content={titleDescription.description} />}
138
+
119
139
  {robots !== null && <meta name="robots" content={robots} />}
120
140
 
121
141
  <link {...canonicalLink} />
@@ -126,6 +146,6 @@ const shouldEmitTwinLink = emitTwinLink ?? Boolean(item)
126
146
 
127
147
  <AeoHead canonical={canonicalHref} emitTwinLink={shouldEmitTwinLink} />
128
148
 
129
- {jsonLd && (
149
+ {jsonLdEntries.map((jsonLd) => (
130
150
  <script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />
131
- )}
151
+ ))}