geo-semantic-layer 2.0.1
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/CHANGELOG.md +289 -0
- package/LICENSE +21 -0
- package/README.md +394 -0
- package/dist/config-BcP2K8Tq.d.ts +150 -0
- package/dist/event-BG0_yYK4.d.ts +2231 -0
- package/dist/generators/index.d.ts +723 -0
- package/dist/generators/index.js +969 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/geo/index.d.ts +38 -0
- package/dist/geo/index.js +107 -0
- package/dist/geo/index.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +1000 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/index.d.ts +97 -0
- package/dist/schemas/index.js +402 -0
- package/dist/schemas/index.js.map +1 -0
- package/package.json +97 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [2.0.0] - 2026-01-06
|
|
6
|
+
|
|
7
|
+
### 🚀 Major Release - Framework-Agnostic Architecture
|
|
8
|
+
|
|
9
|
+
**BREAKING CHANGE:** Complete rewrite to pure framework-agnostic library.
|
|
10
|
+
|
|
11
|
+
#### Why This Change?
|
|
12
|
+
|
|
13
|
+
v1.0 had framework-specific integrations (React, Vue, Angular, Svelte, Astro) which caused:
|
|
14
|
+
- Peer dependency warnings during installation
|
|
15
|
+
- Version conflicts between frameworks
|
|
16
|
+
- Maintenance overhead across multiple framework APIs
|
|
17
|
+
- Larger bundle sizes due to framework dependencies
|
|
18
|
+
|
|
19
|
+
v2.0 solves this by providing **pure functions** that work everywhere.
|
|
20
|
+
|
|
21
|
+
#### Migration Guide
|
|
22
|
+
|
|
23
|
+
**Before (v1.x):**
|
|
24
|
+
```typescript
|
|
25
|
+
import { OrganizationSchema } from 'geo-semantic-layer/react';
|
|
26
|
+
|
|
27
|
+
<OrganizationSchema name="My Company" url="https://example.com" />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**After (v2.0):**
|
|
31
|
+
```typescript
|
|
32
|
+
import { generateOrganizationSchema } from 'geo-semantic-layer';
|
|
33
|
+
|
|
34
|
+
const schema = generateOrganizationSchema({
|
|
35
|
+
name: 'My Company',
|
|
36
|
+
url: 'https://example.com'
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// In React:
|
|
40
|
+
<script
|
|
41
|
+
type="application/ld+json"
|
|
42
|
+
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
// In Vue:
|
|
46
|
+
<script type="application/ld+json">{{ JSON.stringify(schema) }}</script>
|
|
47
|
+
|
|
48
|
+
// In any framework: just insert the JSON-LD yourself
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### ✨ What's New
|
|
52
|
+
|
|
53
|
+
- ✅ **Zero Framework Dependencies** - No React, Vue, Angular, or any framework code
|
|
54
|
+
- ✅ **No Peer Dependencies** - No installation warnings
|
|
55
|
+
- ✅ **Universal Compatibility** - Works in Node.js, Deno, Bun, browsers, edge runtimes
|
|
56
|
+
- ✅ **Tiny Bundle** - Only Zod as dependency (~10KB gzipped)
|
|
57
|
+
- ✅ **Pure Functions** - Predictable, testable, simple
|
|
58
|
+
- ✅ **Use Your Way** - You control how JSON-LD is inserted
|
|
59
|
+
|
|
60
|
+
#### 🗑️ Removed
|
|
61
|
+
|
|
62
|
+
- ❌ Framework-specific components (React, Vue, Angular, Svelte, Astro)
|
|
63
|
+
- ❌ Framework peer dependencies
|
|
64
|
+
- ❌ Framework-specific build targets
|
|
65
|
+
- ❌ Examples folder (no longer needed - it's just pure functions)
|
|
66
|
+
|
|
67
|
+
#### 📦 New Package Structure
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
geo-semantic-layer/
|
|
71
|
+
├── schemas/ # Zod validation schemas
|
|
72
|
+
├── generators/ # Pure generator functions
|
|
73
|
+
└── geo/ # GEO optimization engine
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### 📊 Bundle Size
|
|
77
|
+
|
|
78
|
+
- **Before (v1.0):** ~25KB + framework dependencies
|
|
79
|
+
- **After (v2.0):** ~10KB (including Zod)
|
|
80
|
+
|
|
81
|
+
#### 🎯 Same Features, Better API
|
|
82
|
+
|
|
83
|
+
All the same powerful features:
|
|
84
|
+
- Hallucination Guard (entity validation)
|
|
85
|
+
- Content Density Engine (GEO optimization)
|
|
86
|
+
- Full Zod validation
|
|
87
|
+
- TypeScript type safety
|
|
88
|
+
- All Schema.org types supported
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## [1.0.0] - 2026-01-06
|
|
93
|
+
|
|
94
|
+
### 🎉 Major Release - Unified Package
|
|
95
|
+
|
|
96
|
+
**BREAKING CHANGE:** Migrated from multi-package architecture to unified package.
|
|
97
|
+
|
|
98
|
+
#### Migration
|
|
99
|
+
|
|
100
|
+
**Before:**
|
|
101
|
+
```bash
|
|
102
|
+
npm install @semantic-layer/core @semantic-layer/react
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Now:**
|
|
106
|
+
```bash
|
|
107
|
+
npm install geo-semantic-layer
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Good news:** Imports remain the same! Just change the install command.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// Still works exactly the same
|
|
114
|
+
import { JsonLd } from 'geo-semantic-layer/react'
|
|
115
|
+
import { generateArticle } from 'geo-semantic-layer/core/generators'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### ✨ What's New
|
|
119
|
+
|
|
120
|
+
- ✅ **Single Package** - All frameworks in one npm package
|
|
121
|
+
- ✅ **Synchronized Versions** - All integrations always compatible
|
|
122
|
+
- ✅ **Simplified Installation** - One command for all frameworks
|
|
123
|
+
- ✅ **Perfect Tree-Shaking** - Unused code automatically excluded
|
|
124
|
+
- ✅ **100% Backwards Compatible** - Same API, same imports
|
|
125
|
+
|
|
126
|
+
#### 📦 Package Structure
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
geo-semantic-layer/
|
|
130
|
+
├── core # Framework-agnostic
|
|
131
|
+
├── react # React hooks & components
|
|
132
|
+
├── vue # Vue 3 composables
|
|
133
|
+
├── angular # Angular components
|
|
134
|
+
├── svelte # Svelte components
|
|
135
|
+
└── astro # Astro components
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## [0.1.0] - 2026-01-05
|
|
141
|
+
|
|
142
|
+
### 🎉 Initial Release
|
|
143
|
+
|
|
144
|
+
The first release of Semantic Layer - The ultimate TypeScript library for Generative Engine Optimization (GEO)!
|
|
145
|
+
|
|
146
|
+
### ✨ Features
|
|
147
|
+
|
|
148
|
+
#### Core Package (@semantic-layer/core)
|
|
149
|
+
|
|
150
|
+
- ✅ **Identity Schemas**
|
|
151
|
+
- `generateIdentitySchema()` - Organization and Person schemas
|
|
152
|
+
- Full Zod validation for runtime safety
|
|
153
|
+
- Entity disambiguation support with Wikidata
|
|
154
|
+
|
|
155
|
+
- ✅ **Content Schemas**
|
|
156
|
+
- `generateProductSchema()` - E-commerce products with offers, ratings, reviews
|
|
157
|
+
- `generateArticleSchema()` - Blog posts and news articles
|
|
158
|
+
- `generateFAQSchema()` - FAQ pages for rich search results
|
|
159
|
+
- `generateBreadcrumbSchema()` - Navigation breadcrumbs
|
|
160
|
+
|
|
161
|
+
- ✅ **Utilities**
|
|
162
|
+
- `serializeSchema()` - Convert schemas to JSON strings
|
|
163
|
+
- `generateScriptTag()` - Create complete `<script>` tags
|
|
164
|
+
- Validation helpers (URL, email, date formats)
|
|
165
|
+
|
|
166
|
+
- ✅ **Schema Types**
|
|
167
|
+
- Organization, Person
|
|
168
|
+
- Product, Offer, AggregateRating, Review
|
|
169
|
+
- Article, BlogPosting, NewsArticle
|
|
170
|
+
- FAQPage, Question
|
|
171
|
+
- BreadcrumbList, ListItem
|
|
172
|
+
- WebPage
|
|
173
|
+
|
|
174
|
+
#### React Package (@semantic-layer/react)
|
|
175
|
+
|
|
176
|
+
- ✅ **Components**
|
|
177
|
+
- `<SemanticProvider>` - Root context provider
|
|
178
|
+
- `<OrganizationSchema>` - Organization identity
|
|
179
|
+
- `<PersonSchema>` - Person identity
|
|
180
|
+
- `<ProductSchema>` - E-commerce products
|
|
181
|
+
- `<ArticleSchema>` - Blog posts and articles
|
|
182
|
+
- `<FAQSchema>` - Frequently asked questions
|
|
183
|
+
- `<BreadcrumbSchema>` - Navigation breadcrumbs
|
|
184
|
+
- `<JsonLd>` - Generic schema component
|
|
185
|
+
|
|
186
|
+
- ✅ **Hooks**
|
|
187
|
+
- `useSemanticContext()` - Access configuration
|
|
188
|
+
- `useJsonLd()` - Dynamic schema injection
|
|
189
|
+
|
|
190
|
+
- ✅ **Server Components Support**
|
|
191
|
+
- Ready for React 19 Server Components
|
|
192
|
+
- Optimized for Next.js App Router
|
|
193
|
+
|
|
194
|
+
#### Vue Package (@semantic-layer/vue)
|
|
195
|
+
|
|
196
|
+
- ✅ **Components**
|
|
197
|
+
- `<JsonLd>` - Generic schema component
|
|
198
|
+
- `<OrganizationSchema>` - Organization identity
|
|
199
|
+
|
|
200
|
+
- ✅ **Composables**
|
|
201
|
+
- `useSemanticConfig()` - Access configuration
|
|
202
|
+
- `useJsonLd()` - Dynamic schema injection
|
|
203
|
+
|
|
204
|
+
- ✅ **Vue 3 & Nuxt Support**
|
|
205
|
+
- Full Vue 3 Composition API support
|
|
206
|
+
- Nuxt 3 compatible
|
|
207
|
+
|
|
208
|
+
### 📦 Examples
|
|
209
|
+
|
|
210
|
+
- ✅ **Simple Usage** - Basic TypeScript examples
|
|
211
|
+
- ✅ **Next.js App Router** - Complete e-commerce example
|
|
212
|
+
- Home page
|
|
213
|
+
- Product page with full schema
|
|
214
|
+
- Blog post with Article schema
|
|
215
|
+
- FAQ page with rich results
|
|
216
|
+
|
|
217
|
+
### 🏗️ Architecture
|
|
218
|
+
|
|
219
|
+
- ✅ **Monorepo Structure** - pnpm workspaces
|
|
220
|
+
- ✅ **TypeScript Strict Mode** - Type safety everywhere
|
|
221
|
+
- ✅ **Zod Validation** - Runtime schema validation
|
|
222
|
+
- ✅ **Tree-shakeable** - Import only what you need
|
|
223
|
+
- ✅ **Edge-ready** - Works on Cloudflare Workers, Vercel Edge
|
|
224
|
+
- ✅ **Zero Config** - Smart defaults out of the box
|
|
225
|
+
|
|
226
|
+
### 📊 Performance
|
|
227
|
+
|
|
228
|
+
- **@semantic-layer/core**: 16.81 KB (target < 15KB)
|
|
229
|
+
- **@semantic-layer/react**: 4.03 KB (target < 8KB)
|
|
230
|
+
- **@semantic-layer/vue**: TBD
|
|
231
|
+
- All packages tree-shakeable and minifiable
|
|
232
|
+
|
|
233
|
+
### 🧪 Testing
|
|
234
|
+
|
|
235
|
+
- ✅ 8 unit tests passing (Identity generation, validation, serialization)
|
|
236
|
+
- ✅ Vitest configured for all packages
|
|
237
|
+
- ✅ > 90% coverage target set
|
|
238
|
+
|
|
239
|
+
### 📚 Documentation
|
|
240
|
+
|
|
241
|
+
- ✅ **README.md** - Comprehensive main documentation
|
|
242
|
+
- ✅ **GETTING_STARTED.md** - Quick start guide
|
|
243
|
+
- ✅ **CONTRIBUTING.md** - Contribution guidelines
|
|
244
|
+
- ✅ **LICENSE** - MIT License
|
|
245
|
+
- ✅ Package-specific READMEs for core, react, vue
|
|
246
|
+
- ✅ Inline JSDoc comments on all public APIs
|
|
247
|
+
|
|
248
|
+
### 🛠️ Development
|
|
249
|
+
|
|
250
|
+
- ✅ **Build System** - tsup for fast builds
|
|
251
|
+
- ✅ **Linting** - ESLint with TypeScript support
|
|
252
|
+
- ✅ **Formatting** - Prettier configured
|
|
253
|
+
- ✅ **Git Hooks** - Ready for pre-commit hooks
|
|
254
|
+
|
|
255
|
+
### 🎯 GEO Features
|
|
256
|
+
|
|
257
|
+
- ✅ **Entity Disambiguation** - Wikidata ID support
|
|
258
|
+
- ✅ **Citation-Ready Content** - Structured fact representation
|
|
259
|
+
- ✅ **AI-Friendly Markup** - Optimized for ChatGPT, Gemini, Perplexity
|
|
260
|
+
- ✅ **Rich Snippets** - Google Search rich results
|
|
261
|
+
- ✅ **Knowledge Graph** - Root identity architecture
|
|
262
|
+
|
|
263
|
+
### 🔮 Planned for Future Releases
|
|
264
|
+
|
|
265
|
+
- [ ] @semantic-layer/astro package
|
|
266
|
+
- [ ] @semantic-layer/svelte package
|
|
267
|
+
- [ ] CLI tool (`create-semantic-layer`)
|
|
268
|
+
- [ ] Visual schema builder
|
|
269
|
+
- [ ] Google Rich Results Test integration
|
|
270
|
+
- [ ] Analytics dashboard
|
|
271
|
+
- [ ] More schema types (Recipe, Event, LocalBusiness, etc.)
|
|
272
|
+
- [ ] Rust-based validator (WASM)
|
|
273
|
+
|
|
274
|
+
### 📝 Notes
|
|
275
|
+
|
|
276
|
+
This is an alpha release focused on establishing the core architecture and proving the concept. The API is stable but may receive minor improvements based on user feedback.
|
|
277
|
+
|
|
278
|
+
### 🙏 Credits
|
|
279
|
+
|
|
280
|
+
Built with ❤️ by the Semantic Layer Contributors
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Links
|
|
285
|
+
|
|
286
|
+
- [GitHub Repository](https://github.com/yourusername/semantic-layer)
|
|
287
|
+
- [Documentation](./readme.md)
|
|
288
|
+
- [Getting Started](./GETTING_STARTED.md)
|
|
289
|
+
- [Contributing](./CONTRIBUTING.md)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rafael Calderón (BDOvenbird Engineering)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# GEO Semantic Layer
|
|
2
|
+
|
|
3
|
+
Framework-agnostic TypeScript library for Generative Engine Optimization (GEO) and structured data automation.
|
|
4
|
+
|
|
5
|
+
Build type-safe, validated JSON-LD schemas that work in any JavaScript environment: React, Vue, Angular, Svelte, Astro, Next.js, Nuxt, Remix, Node.js, Deno, Bun, edge runtimes, and vanilla JavaScript.
|
|
6
|
+
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://www.npmjs.com/package/geo-semantic-layer)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Why v2.0?
|
|
14
|
+
|
|
15
|
+
Version 2.0 is a complete rewrite focused on universality and simplicity.
|
|
16
|
+
|
|
17
|
+
**What changed:**
|
|
18
|
+
- Zero framework dependencies (only Zod for validation)
|
|
19
|
+
- No peer dependency warnings during installation
|
|
20
|
+
- Works in any JavaScript environment
|
|
21
|
+
- Smaller bundle size (~10KB vs ~25KB)
|
|
22
|
+
- Pure functions instead of framework-specific components
|
|
23
|
+
|
|
24
|
+
**What stayed the same:**
|
|
25
|
+
- All Schema.org types supported
|
|
26
|
+
- Full TypeScript type safety
|
|
27
|
+
- Zod runtime validation
|
|
28
|
+
- GEO optimization features
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install geo-semantic-layer
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
No framework-specific packages. No peer dependencies.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { generateArticleSchema } from 'geo-semantic-layer';
|
|
46
|
+
|
|
47
|
+
const schema = generateArticleSchema({
|
|
48
|
+
headline: 'The Future of GEO in 2026',
|
|
49
|
+
image: 'https://example.com/article.jpg',
|
|
50
|
+
author: 'John Doe',
|
|
51
|
+
datePublished: '2026-01-06',
|
|
52
|
+
description: 'How AI models consume structured data',
|
|
53
|
+
publisher: {
|
|
54
|
+
name: 'My Site',
|
|
55
|
+
logo: 'https://example.com/logo.png'
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Insert into your HTML:
|
|
60
|
+
// <script type="application/ld+json">{JSON.stringify(schema)}</script>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Framework Integration
|
|
66
|
+
|
|
67
|
+
### React / Next.js
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { generateOrganizationSchema } from 'geo-semantic-layer';
|
|
71
|
+
|
|
72
|
+
export default function RootLayout({ children }) {
|
|
73
|
+
const schema = generateOrganizationSchema({
|
|
74
|
+
name: 'My Company',
|
|
75
|
+
url: 'https://example.com',
|
|
76
|
+
logo: 'https://example.com/logo.png',
|
|
77
|
+
sameAs: [
|
|
78
|
+
'https://wikidata.org/wiki/Q123',
|
|
79
|
+
'https://linkedin.com/company/example'
|
|
80
|
+
]
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<html>
|
|
85
|
+
<head>
|
|
86
|
+
<script
|
|
87
|
+
type="application/ld+json"
|
|
88
|
+
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
|
|
89
|
+
/>
|
|
90
|
+
</head>
|
|
91
|
+
<body>{children}</body>
|
|
92
|
+
</html>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Vue 3 / Nuxt
|
|
98
|
+
|
|
99
|
+
```vue
|
|
100
|
+
<script setup>
|
|
101
|
+
import { generateProductSchema } from 'geo-semantic-layer';
|
|
102
|
+
|
|
103
|
+
const schema = generateProductSchema({
|
|
104
|
+
name: 'Wireless Headphones',
|
|
105
|
+
description: 'Premium noise-cancelling headphones',
|
|
106
|
+
image: 'https://example.com/headphones.jpg',
|
|
107
|
+
brand: 'AudioTech',
|
|
108
|
+
offers: {
|
|
109
|
+
price: 299.99,
|
|
110
|
+
priceCurrency: 'USD',
|
|
111
|
+
availability: 'InStock',
|
|
112
|
+
url: 'https://example.com/products/headphones'
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<template>
|
|
118
|
+
<Head>
|
|
119
|
+
<script type="application/ld+json">{{ JSON.stringify(schema) }}</script>
|
|
120
|
+
</Head>
|
|
121
|
+
</template>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Svelte / SvelteKit
|
|
125
|
+
|
|
126
|
+
```svelte
|
|
127
|
+
<script>
|
|
128
|
+
import { generateFAQSchema } from 'geo-semantic-layer';
|
|
129
|
+
|
|
130
|
+
const schema = generateFAQSchema({
|
|
131
|
+
questions: [
|
|
132
|
+
{
|
|
133
|
+
question: 'What is GEO?',
|
|
134
|
+
answer: 'Generative Engine Optimization for AI search engines.'
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
question: 'How does it work?',
|
|
138
|
+
answer: 'By providing structured data AI models can easily consume.'
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
});
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
<svelte:head>
|
|
145
|
+
<script type="application/ld+json">{JSON.stringify(schema)}</script>
|
|
146
|
+
</svelte:head>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Astro
|
|
150
|
+
|
|
151
|
+
```astro
|
|
152
|
+
---
|
|
153
|
+
import { generateBreadcrumbSchema } from 'geo-semantic-layer';
|
|
154
|
+
|
|
155
|
+
const schema = generateBreadcrumbSchema({
|
|
156
|
+
items: [
|
|
157
|
+
{ name: 'Home', url: 'https://example.com' },
|
|
158
|
+
{ name: 'Products', url: 'https://example.com/products' },
|
|
159
|
+
{ name: 'Headphones', url: 'https://example.com/products/headphones' }
|
|
160
|
+
]
|
|
161
|
+
});
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
<html>
|
|
165
|
+
<head>
|
|
166
|
+
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
|
|
167
|
+
</head>
|
|
168
|
+
<body>
|
|
169
|
+
<slot />
|
|
170
|
+
</body>
|
|
171
|
+
</html>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Angular
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { Component } from '@angular/core';
|
|
178
|
+
import { generateLocalBusinessSchema } from 'geo-semantic-layer';
|
|
179
|
+
|
|
180
|
+
@Component({
|
|
181
|
+
selector: 'app-root',
|
|
182
|
+
template: `
|
|
183
|
+
<div [innerHTML]="schemaScript"></div>
|
|
184
|
+
`
|
|
185
|
+
})
|
|
186
|
+
export class AppComponent {
|
|
187
|
+
schema = generateLocalBusinessSchema({
|
|
188
|
+
name: 'Coffee Shop Downtown',
|
|
189
|
+
address: {
|
|
190
|
+
streetAddress: '123 Main St',
|
|
191
|
+
addressLocality: 'New York',
|
|
192
|
+
addressRegion: 'NY',
|
|
193
|
+
postalCode: '10001',
|
|
194
|
+
addressCountry: 'US'
|
|
195
|
+
},
|
|
196
|
+
geo: {
|
|
197
|
+
latitude: 40.7128,
|
|
198
|
+
longitude: -74.0060
|
|
199
|
+
},
|
|
200
|
+
telephone: '+1-555-123-4567'
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
get schemaScript() {
|
|
204
|
+
return `<script type="application/ld+json">${JSON.stringify(this.schema)}</script>`;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Node.js / Express
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
import express from 'express';
|
|
213
|
+
import { generateWebPageSchema } from 'geo-semantic-layer';
|
|
214
|
+
|
|
215
|
+
const app = express();
|
|
216
|
+
|
|
217
|
+
app.get('/', (req, res) => {
|
|
218
|
+
const schema = generateWebPageSchema({
|
|
219
|
+
name: 'Homepage',
|
|
220
|
+
description: 'Welcome to our site',
|
|
221
|
+
url: 'https://example.com'
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
res.send(`
|
|
225
|
+
<!DOCTYPE html>
|
|
226
|
+
<html>
|
|
227
|
+
<head>
|
|
228
|
+
<script type="application/ld+json">
|
|
229
|
+
${JSON.stringify(schema)}
|
|
230
|
+
</script>
|
|
231
|
+
</head>
|
|
232
|
+
<body>
|
|
233
|
+
<h1>Hello World</h1>
|
|
234
|
+
</body>
|
|
235
|
+
</html>
|
|
236
|
+
`);
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Available Schemas
|
|
243
|
+
|
|
244
|
+
| Generator | Description |
|
|
245
|
+
|-----------|-------------|
|
|
246
|
+
| `generateOrganizationSchema()` | Company/business information |
|
|
247
|
+
| `generatePersonSchema()` | Individual person profiles |
|
|
248
|
+
| `generateProductSchema()` | E-commerce products with ratings |
|
|
249
|
+
| `generateArticleSchema()` | Blog posts and articles |
|
|
250
|
+
| `generateFAQSchema()` | Frequently asked questions |
|
|
251
|
+
| `generateBreadcrumbSchema()` | Navigation breadcrumbs |
|
|
252
|
+
| `generateLocalBusinessSchema()` | Physical business locations |
|
|
253
|
+
| `generateEventSchema()` | Events and conferences |
|
|
254
|
+
| `generateWebPageSchema()` | Individual web pages |
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Features
|
|
259
|
+
|
|
260
|
+
### GEO Optimization
|
|
261
|
+
|
|
262
|
+
Optimize JSON-LD for AI model consumption:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
import { generateArticleSchema } from 'geo-semantic-layer';
|
|
266
|
+
|
|
267
|
+
const schema = generateArticleSchema({
|
|
268
|
+
headline: 'My Article',
|
|
269
|
+
author: 'John Doe',
|
|
270
|
+
datePublished: '2026-01-06',
|
|
271
|
+
articleBody: 'Very long article content...',
|
|
272
|
+
geo: {
|
|
273
|
+
contentDensity: 'high' // Prunes decorative data for LLMs
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Hallucination Guard
|
|
279
|
+
|
|
280
|
+
Validates entity links against authoritative sources (Wikidata, LinkedIn) to prevent AI misattribution.
|
|
281
|
+
|
|
282
|
+
### Content Density Engine
|
|
283
|
+
|
|
284
|
+
Automatically prunes decorative data to generate high-density JSON-LD optimized for LLM context windows.
|
|
285
|
+
|
|
286
|
+
### Schema Validation
|
|
287
|
+
|
|
288
|
+
All schemas validated with Zod:
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
import { ArticleSchema } from 'geo-semantic-layer/schemas';
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
const validated = ArticleSchema.parse(myData);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
console.error('Invalid schema:', error);
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### TypeScript Types
|
|
301
|
+
|
|
302
|
+
Full type safety:
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
import type { Article, Product, Organization } from 'geo-semantic-layer';
|
|
306
|
+
|
|
307
|
+
const article: Article = {
|
|
308
|
+
'@context': 'https://schema.org',
|
|
309
|
+
'@type': 'Article',
|
|
310
|
+
headline: 'My Article',
|
|
311
|
+
// TypeScript enforces correct structure
|
|
312
|
+
};
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Package Exports
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
// Main entry - all generators and schemas
|
|
321
|
+
import { generateArticleSchema } from 'geo-semantic-layer';
|
|
322
|
+
|
|
323
|
+
// Schemas only
|
|
324
|
+
import { ArticleSchema } from 'geo-semantic-layer/schemas';
|
|
325
|
+
|
|
326
|
+
// Generators only
|
|
327
|
+
import { generateArticleSchema } from 'geo-semantic-layer/generators';
|
|
328
|
+
|
|
329
|
+
// GEO Engine only
|
|
330
|
+
import { GeoProcessor } from 'geo-semantic-layer/geo';
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Migration from v1.x
|
|
336
|
+
|
|
337
|
+
**Before (v1.x):**
|
|
338
|
+
```typescript
|
|
339
|
+
import { OrganizationSchema } from 'geo-semantic-layer/react';
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**After (v2.0):**
|
|
343
|
+
```typescript
|
|
344
|
+
import { generateOrganizationSchema } from 'geo-semantic-layer';
|
|
345
|
+
|
|
346
|
+
// In your React component:
|
|
347
|
+
const schema = generateOrganizationSchema({ name: 'My Company', url: '...' });
|
|
348
|
+
|
|
349
|
+
return (
|
|
350
|
+
<script
|
|
351
|
+
type="application/ld+json"
|
|
352
|
+
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
|
|
353
|
+
/>
|
|
354
|
+
);
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
The core API remains the same. You now control how JSON-LD is inserted into your application.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Why This Approach?
|
|
362
|
+
|
|
363
|
+
**Problems with v1.x:**
|
|
364
|
+
- Framework components caused peer dependency warnings
|
|
365
|
+
- Version conflicts between frameworks
|
|
366
|
+
- Maintenance overhead across multiple framework APIs
|
|
367
|
+
- Larger bundle sizes
|
|
368
|
+
|
|
369
|
+
**Benefits of v2.0:**
|
|
370
|
+
- Pure functions work everywhere
|
|
371
|
+
- No framework dependencies
|
|
372
|
+
- One install, use anywhere
|
|
373
|
+
- Smaller bundle size
|
|
374
|
+
- Easier maintenance
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Contributing
|
|
379
|
+
|
|
380
|
+
Contributions welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## License
|
|
385
|
+
|
|
386
|
+
MIT © 2026 Rafael Calderón (BDOvenbird Engineering)
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Links
|
|
391
|
+
|
|
392
|
+
- [npm](https://www.npmjs.com/package/geo-semantic-layer)
|
|
393
|
+
- [GitHub](https://github.com/bdovenbird/semantic-layer)
|
|
394
|
+
- [Issues](https://github.com/bdovenbird/semantic-layer/issues)
|